[variant]

# 22 General utilities library [[utilities]](./#utilities)

## 22.6 Variants [variant]

### [22.6.1](#general) General [[variant.general]](variant.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5532)

A variant object holds and manages the lifetime of a value[.](#general-1.sentence-1)

If the variant holds a value, that value's type has to be one
of the template argument types given to variant[.](#general-1.sentence-2)

These template arguments are called alternatives[.](#general-1.sentence-3)

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5538)

In [variant],*GET* denotes
a set of exposition-only function templates ([[variant.get]](#get "22.6.5 Value access"))[.](#general-2.sentence-1)

### [22.6.2](#syn) Header <variant> synopsis [[variant.syn]](variant.syn)

// mostly freestanding#include <compare> // see [[compare.syn]](compare.syn "17.12.1 Header <compare> synopsis")namespace std {// [[variant.variant]](#variant "22.6.3 Class template variant"), class template varianttemplate<class... Types>class variant; // [[variant.helper]](#helper "22.6.4 variant helper classes"), variant helper classestemplate<class T> struct variant_size; // *not defined*template<class T> struct variant_size<const T>; template<class T>constexpr size_t [variant_size_v](#lib:variant_size_v "22.6.2 Header <variant> synopsis [variant.syn]") = variant_size<T>::value; template<class... Types>struct variant_size<variant<Types...>>; template<size_t I, class T> struct variant_alternative; // *not defined*template<size_t I, class T> struct variant_alternative<I, const T>; template<size_t I, class T>using [variant_alternative_t](#lib:variant_alternative_t "22.6.2 Header <variant> synopsis [variant.syn]") = typename variant_alternative<I, T>::type; template<size_t I, class... Types>struct variant_alternative<I, variant<Types...>>; inline constexpr size_t variant_npos = -1; // [[variant.get]](#get "22.6.5 Value access"), value accesstemplate<class T, class... Types>constexpr bool holds_alternative(const variant<Types...>&) noexcept; template<size_t I, class... Types>constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&); // freestanding-deletedtemplate<size_t I, class... Types>constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&); // freestanding-deletedtemplate<size_t I, class... Types>constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&); // freestanding-deletedtemplate<size_t I, class... Types>constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&); // freestanding-deletedtemplate<class T, class... Types>constexpr T& get(variant<Types...>&); // freestanding-deletedtemplate<class T, class... Types>constexpr T&& get(variant<Types...>&&); // freestanding-deletedtemplate<class T, class... Types>constexpr const T& get(const variant<Types...>&); // freestanding-deletedtemplate<class T, class... Types>constexpr const T&& get(const variant<Types...>&&); // freestanding-deletedtemplate<size_t I, class... Types>constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>> get_if(variant<Types...>*) noexcept; template<size_t I, class... Types>constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>> get_if(const variant<Types...>*) noexcept; template<class T, class... Types>constexpr add_pointer_t<T> get_if(variant<Types...>*) noexcept; template<class T, class... Types>constexpr add_pointer_t<const T> get_if(const variant<Types...>*) noexcept; // [[variant.relops]](#relops "22.6.6 Relational operators"), relational operatorstemplate<class... Types>constexpr bool operator==(const variant<Types...>&, const variant<Types...>&); template<class... Types>constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&); template<class... Types>constexpr bool operator<(const variant<Types...>&, const variant<Types...>&); template<class... Types>constexpr bool operator>(const variant<Types...>&, const variant<Types...>&); template<class... Types>constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&); template<class... Types>constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&); template<class... Types> requires ([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")<Types> && ...)constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>operator<=>(const variant<Types...>&, const variant<Types...>&); // [[variant.visit]](#visit "22.6.7 Visitation"), visitationtemplate<class Visitor, class... Variants>constexpr *see below* visit(Visitor&&, Variants&&...); template<class R, class Visitor, class... Variants>constexpr R visit(Visitor&&, Variants&&...); // [[variant.monostate]](#monostate "22.6.8 Class monostate"), class monostatestruct monostate; // [[variant.monostate.relops]](#monostate.relops "22.6.9 monostate relational operators"), monostate relational operatorsconstexpr bool operator==(monostate, monostate) noexcept; constexpr strong_ordering operator<=>(monostate, monostate) noexcept; // [[variant.specalg]](#specalg "22.6.10 Specialized algorithms"), specialized algorithmstemplate<class... Types>constexpr void swap(variant<Types...>&, variant<Types...>&) noexcept(*see below*); // [[variant.bad.access]](#bad.access "22.6.11 Class bad_­variant_­access"), class bad_variant_accessclass bad_variant_access; // [[variant.hash]](#hash "22.6.12 Hash support"), hash supporttemplate<class T> struct hash; template<class... Types> struct hash<variant<Types...>>; template<> struct hash<monostate>;}

### [22.6.3](#variant) Class template variant [[variant.variant]](variant.variant)

#### [22.6.3.1](#variant.general) General [[variant.variant.general]](variant.variant.general)

namespace std {template<class... Types>class variant {public:// [[variant.ctor]](#ctor "22.6.3.2 Constructors"), constructorsconstexpr variant() noexcept(*see below*); constexpr variant(const variant&); constexpr variant(variant&&) noexcept(*see below*); template<class T>constexpr variant(T&&) noexcept(*see below*); template<class T, class... Args>constexpr explicit variant(in_place_type_t<T>, Args&&...); template<class T, class U, class... Args>constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...); template<size_t I, class... Args>constexpr explicit variant(in_place_index_t<I>, Args&&...); template<size_t I, class U, class... Args>constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...); // [[variant.dtor]](#dtor "22.6.3.3 Destructor"), destructorconstexpr ~variant(); // [[variant.assign]](#assign "22.6.3.4 Assignment"), assignmentconstexpr variant& operator=(const variant&); constexpr variant& operator=(variant&&) noexcept(*see below*); template<class T> constexpr variant& operator=(T&&) noexcept(*see below*); // [[variant.mod]](#mod "22.6.3.5 Modifiers"), modifierstemplate<class T, class... Args>constexpr T& emplace(Args&&...); template<class T, class U, class... Args>constexpr T& emplace(initializer_list<U>, Args&&...); template<size_t I, class... Args>constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&...); template<size_t I, class U, class... Args>constexpr variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...); // [[variant.status]](#status "22.6.3.6 Value status"), value statusconstexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // [[variant.swap]](#swap "22.6.3.7 Swap"), swapconstexpr void swap(variant&) noexcept(*see below*); // [[variant.visit]](#visit "22.6.7 Visitation"), visitationtemplate<class Self, class Visitor>constexpr decltype(auto) visit(this Self&&, Visitor&&); template<class R, class Self, class Visitor>constexpr R visit(this Self&&, Visitor&&); };}

[1](#variant.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5722)

Any instance of variant at any given time either holds a value
of one of its alternative types or holds no value[.](#variant.general-1.sentence-1)

When an instance of variant holds a value of alternative type T,
it means that a value of type T, referred to as the variant object's [*contained value*](#def:contained_value,variant "22.6.3.1 General [variant.variant.general]"),
is nested within ([[intro.object]](intro.object "6.8.2 Object model")) thevariant object[.](#variant.general-1.sentence-2)

[2](#variant.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5731)

All types in Types shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#variant.general-2.sentence-1)

[3](#variant.general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5735)

A program that instantiates the definition of variant with
no template arguments is ill-formed[.](#variant.general-3.sentence-1)

[4](#variant.general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5739)

If a program declares an explicit or partial specialization of variant,
the program is ill-formed, no diagnostic required[.](#variant.general-4.sentence-1)

#### [22.6.3.2](#ctor) Constructors [[variant.ctor]](variant.ctor)

[1](#ctor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5745)

In the descriptions that follow, let i be in the range [0, sizeof...(Types)),
and Ti be the ith type in Types[.](#ctor-1.sentence-1)

[ð](#lib:variant,constructor)

`constexpr variant() noexcept(see below);
`

[2](#ctor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5755)

*Constraints*: is_default_constructible_v<T0> is true[.](#ctor-2.sentence-1)

[3](#ctor-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5759)

*Effects*: Constructs a variant holding a value-initialized value of type T0[.](#ctor-3.sentence-1)

[4](#ctor-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5763)

*Postconditions*: valueless_by_exception() is false and index() is 0[.](#ctor-4.sentence-1)

[5](#ctor-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5767)

*Throws*: Any exception thrown by the value-initialization of T0[.](#ctor-5.sentence-1)

[6](#ctor-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5771)

*Remarks*: This function is constexpr if and only if the
value-initialization of the alternative type T0 would be constexpr-suitable ([[dcl.constexpr]](dcl.constexpr "9.2.6 The constexpr and consteval specifiers"))[.](#ctor-6.sentence-1)

The exception specification is equivalent tois_nothrow_default_constructible_v<T0>[.](#ctor-6.sentence-2)

[*Note [1](#ctor-note-1)*:

See also class monostate[.](#ctor-6.sentence-3)

â *end note*]

[ð](#lib:variant,constructor_)

`constexpr variant(const variant& w);
`

[7](#ctor-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5789)

*Effects*: If w holds a value, initializes the variant to hold the same
alternative as w and direct-initializes the contained value
with *GET*<j>(w), where j is w.index()[.](#ctor-7.sentence-1)

Otherwise, initializes the variant to not hold a value[.](#ctor-7.sentence-2)

[8](#ctor-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5796)

*Throws*: Any exception thrown by direct-initializing any Ti for all i[.](#ctor-8.sentence-1)

[9](#ctor-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5800)

*Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v<Ti> is true for all i[.](#ctor-9.sentence-1)

If is_trivially_copy_constructible_v<Ti> is true for all i, this constructor is trivial[.](#ctor-9.sentence-2)

[ð](#lib:variant,constructor__)

`constexpr variant(variant&& w) noexcept(see below);
`

[10](#ctor-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5814)

*Constraints*: is_move_constructible_v<Ti> is true for all i[.](#ctor-10.sentence-1)

[11](#ctor-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5818)

*Effects*: If w holds a value, initializes the variant to hold the same
alternative as w and direct-initializes the contained value with*GET*<j>(std​::​move(w)), where j is w.index()[.](#ctor-11.sentence-1)

Otherwise, initializes the variant to not hold a value[.](#ctor-11.sentence-2)

[12](#ctor-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5825)

*Throws*: Any exception thrown by move-constructing any Ti for all i[.](#ctor-12.sentence-1)

[13](#ctor-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5829)

*Remarks*: The exception specification is equivalent to the logical and ofis_nothrow_move_constructible_v<Ti> for all i[.](#ctor-13.sentence-1)

If is_trivially_move_constructible_v<Ti> is true for all i, this constructor is trivial[.](#ctor-13.sentence-2)

[ð](#lib:variant,constructor___)

`template<class T> constexpr variant(T&& t) noexcept(see below);
`

[14](#ctor-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5843)

Let Tj be a type that is determined as follows:
build an imaginary function *FUN*(Ti) for each alternative type Ti for which Ti x[] = {std​::​forward<T>(t)}; is well-formed for some invented variable x[.](#ctor-14.sentence-1)

The overload *FUN*(Tj) selected by overload
resolution for the expression *FUN*(std​::​forward<T>(​t)) defines
the alternative Tj which is the type of the contained value after
construction[.](#ctor-14.sentence-2)

[15](#ctor-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5854)

*Constraints*: 

- [(15.1)](#ctor-15.1)

sizeof...(Types) is nonzero,

- [(15.2)](#ctor-15.2)

is_same_v<remove_cvref_t<T>, variant> is false,

- [(15.3)](#ctor-15.3)

remove_cvref_t<T> is neither
a specialization of in_place_type_t nor
a specialization of in_place_index_t,

- [(15.4)](#ctor-15.4)

is_constructible_v<Tj, T> is true, and

- [(15.5)](#ctor-15.5)

the expression *FUN*(​std​::​forward<T>(t)) (with *FUN* being the above-mentioned set of
imaginary functions) is well-formed[.](#ctor-15.sentence-1)
  [*Note [2](#ctor-note-2)*:
  variant<string, string> v("abc"); is ill-formed, as both alternative types have an equally viable constructor
for the argument[.](#ctor-15.5.sentence-2)
 â *end note*]

[16](#ctor-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5884)

*Effects*: Initializes *this to hold the alternative type Tj and
direct-non-list-initializes the contained value with std​::​forward<T>(t)[.](#ctor-16.sentence-1)

[17](#ctor-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5889)

*Postconditions*: holds_alternative<Tj>(*this) is true[.](#ctor-17.sentence-1)

[18](#ctor-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5893)

*Throws*: Any exception thrown by the initialization of the selected alternative Tj[.](#ctor-18.sentence-1)

[19](#ctor-19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5897)

*Remarks*: The exception specification is equivalent tois_nothrow_constructible_v<Tj, T>[.](#ctor-19.sentence-1)

If Tj's selected constructor is a constexpr constructor,
this constructor is a constexpr constructor[.](#ctor-19.sentence-2)

[ð](#lib:variant,constructor____)

`template<class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
`

[20](#ctor-20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5911)

*Constraints*: 

- [(20.1)](#ctor-20.1)

There is exactly one occurrence of T in Types... and

- [(20.2)](#ctor-20.2)

is_constructible_v<T, Args...> is true[.](#ctor-20.sentence-1)

[21](#ctor-21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5918)

*Effects*: Direct-non-list-initializes the contained value of type T with std​::​forward<Args>(args)...[.](#ctor-21.sentence-1)

[22](#ctor-22)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5923)

*Postconditions*: holds_alternative<T>(*this) is true[.](#ctor-22.sentence-1)

[23](#ctor-23)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5927)

*Throws*: Any exception thrown by calling the selected constructor of T[.](#ctor-23.sentence-1)

[24](#ctor-24)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5931)

*Remarks*: If T's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#ctor-24.sentence-1)

[ð](#lib:variant,constructor_____)

`template<class T, class U, class... Args>
  constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
`

[25](#ctor-25)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5944)

*Constraints*: 

- [(25.1)](#ctor-25.1)

There is exactly one occurrence of T in Types... and

- [(25.2)](#ctor-25.2)

is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#ctor-25.sentence-1)

[26](#ctor-26)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5951)

*Effects*: Direct-non-list-initializes the contained value of type T with il, std​::​forward<Args>(​args)...[.](#ctor-26.sentence-1)

[27](#ctor-27)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5956)

*Postconditions*: holds_alternative<T>(*this) is true[.](#ctor-27.sentence-1)

[28](#ctor-28)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5960)

*Throws*: Any exception thrown by calling the selected constructor of T[.](#ctor-28.sentence-1)

[29](#ctor-29)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5964)

*Remarks*: If T's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#ctor-29.sentence-1)

[ð](#lib:variant,constructor______)

`template<size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
`

[30](#ctor-30)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5976)

*Constraints*: 

- [(30.1)](#ctor-30.1)

I is less than sizeof...(Types) and

- [(30.2)](#ctor-30.2)

is_constructible_v<TI, Args...> is true[.](#ctor-30.sentence-1)

[31](#ctor-31)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5985)

*Effects*: Direct-non-list-initializes the contained value of type TI with std​::​forward<Args>(args)...[.](#ctor-31.sentence-1)

[32](#ctor-32)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5990)

*Postconditions*: index() is I[.](#ctor-32.sentence-1)

[33](#ctor-33)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5994)

*Throws*: Any exception thrown by calling the selected constructor of TI[.](#ctor-33.sentence-1)

[34](#ctor-34)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5998)

*Remarks*: If TI's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#ctor-34.sentence-1)

[ð](#lib:variant,constructor_______)

`template<size_t I, class U, class... Args>
  constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
`

[35](#ctor-35)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6011)

*Constraints*: 

- [(35.1)](#ctor-35.1)

I is less than sizeof...(Types) and

- [(35.2)](#ctor-35.2)

is_constructible_v<TI, initializer_list<U>&, Args...> is true[.](#ctor-35.sentence-1)

[36](#ctor-36)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6020)

*Effects*: Direct-non-list-initializes the contained value of type TI with il, std​::​forward<Args>(​args)...[.](#ctor-36.sentence-1)

[37](#ctor-37)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6025)

*Postconditions*: index() is I[.](#ctor-37.sentence-1)

[38](#ctor-38)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6029)

*Remarks*: If TI's selected constructor is a constexpr constructor, this
constructor is a constexpr constructor[.](#ctor-38.sentence-1)

#### [22.6.3.3](#dtor) Destructor [[variant.dtor]](variant.dtor)

[ð](#lib:variant,destructor)

`constexpr ~variant();
`

[1](#dtor-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6043)

*Effects*: If valueless_by_exception() is false,
destroys the currently contained value[.](#dtor-1.sentence-1)

[2](#dtor-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6048)

*Remarks*: If is_trivially_destructible_v<Ti> is true for all Ti,
then this destructor is trivial[.](#dtor-2.sentence-1)

#### [22.6.3.4](#assign) Assignment [[variant.assign]](variant.assign)

[ð](#lib:operator=,variant)

`constexpr variant& operator=(const variant& rhs);
`

[1](#assign-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6062)

Let j be rhs.index()[.](#assign-1.sentence-1)

[2](#assign-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6065)

*Effects*: 

- [(2.1)](#assign-2.1)

  If neither *this nor rhs holds a value, there is no effect[.](#assign-2.1.sentence-1)

- [(2.2)](#assign-2.2)

  Otherwise, if *this holds a value but rhs does not, destroys the value
contained in *this and sets *this to not hold a value[.](#assign-2.2.sentence-1)

- [(2.3)](#assign-2.3)

  Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this[.](#assign-2.3.sentence-1)

- [(2.4)](#assign-2.4)

  Otherwise, if either is_nothrow_copy_constructible_v<Tj> is true oris_nothrow_move_constructible_v<Tj> is false,
equivalent to emplace<j>(*GET*<j>(rhs))[.](#assign-2.4.sentence-1)

- [(2.5)](#assign-2.5)

  Otherwise, equivalent to operator=(variant(rhs))[.](#assign-2.5.sentence-1)

[3](#assign-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6085)

*Postconditions*: index() == rhs.index()[.](#assign-3.sentence-1)

[4](#assign-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6089)

*Returns*: *this[.](#assign-4.sentence-1)

[5](#assign-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6093)

*Remarks*: This operator is defined as deleted unlessis_copy_constructible_v<Ti> &&is_copy_assignable_v<Ti> is true for all i[.](#assign-5.sentence-1)

If is_trivially_copy_constructible_v<Ti> &&is_trivially_copy_assignable_v<Ti> &&is_trivially_destructible_v<Ti> is true for all i, this assignment operator is trivial[.](#assign-5.sentence-2)

[ð](#lib:operator=,variant_)

`constexpr variant& operator=(variant&& rhs) noexcept(see below);
`

[6](#assign-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6111)

Let j be rhs.index()[.](#assign-6.sentence-1)

[7](#assign-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6114)

*Constraints*: is_move_constructible_v<Ti> &&is_move_assignable_v<Ti> istrue for all i[.](#assign-7.sentence-1)

[8](#assign-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6120)

*Effects*: 

- [(8.1)](#assign-8.1)

  If neither *this nor rhs holds a value, there is no effect[.](#assign-8.1.sentence-1)

- [(8.2)](#assign-8.2)

  Otherwise, if *this holds a value but rhs does not, destroys the value
contained in *this and sets *this to not hold a value[.](#assign-8.2.sentence-1)

- [(8.3)](#assign-8.3)

  Otherwise, if index() == j, assigns *GET*<j>(std​::​move(rhs)) to
the value contained in *this[.](#assign-8.3.sentence-1)

- [(8.4)](#assign-8.4)

  Otherwise, equivalent to emplace<j>(*GET*<j>(std​::​move(rhs)))[.](#assign-8.4.sentence-1)

[9](#assign-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6135)

*Returns*: *this[.](#assign-9.sentence-1)

[10](#assign-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6139)

*Remarks*: If is_trivially_move_constructible_v<Ti> &&is_trivially_move_assignable_v<Ti> &&is_trivially_destructible_v<Ti> is true for all i, this assignment operator is trivial[.](#assign-10.sentence-1)

The exception specification is equivalent tois_nothrow_move_constructible_v<Ti> && is_nothrow_move_assignable_v<Ti> for all i[.](#assign-10.sentence-2)

- [(10.1)](#assign-10.1)

  If an exception is thrown during the call to Tj's move construction
(with j being rhs.index()), the variant will hold no value[.](#assign-10.1.sentence-1)

- [(10.2)](#assign-10.2)

  If an exception is thrown during the call to Tj's move assignment,
the state of the contained value is as defined by the exception safety
guarantee of Tj's move assignment; index() will be j[.](#assign-10.2.sentence-1)

[ð](#lib:operator=,variant__)

`template<class T> constexpr variant& operator=(T&& t) noexcept(see below);
`

[11](#assign-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6162)

Let Tj be a type that is determined as follows:
build an imaginary function *FUN*(Ti) for each alternative type Ti for which Ti x[] = {std​::​forward<T>(t)}; is well-formed for some invented variable x[.](#assign-11.sentence-1)

The overload *FUN*(Tj) selected by overload
resolution for the expression *FUN*(std​::​forward<T>(​t)) defines
the alternative Tj which is the type of the contained value after
assignment[.](#assign-11.sentence-2)

[12](#assign-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6173)

*Constraints*: 

- [(12.1)](#assign-12.1)

is_same_v<remove_cvref_t<T>, variant> is false,

- [(12.2)](#assign-12.2)

is_assignable_v<Tj&, T> && is_constructible_v<Tj, T> is true, and

- [(12.3)](#assign-12.3)

the expression *FUN*(std​::​forward<T>(t)) (with *FUN* being the above-mentioned set
of imaginary functions) is well-formed[.](#assign-12.sentence-1)
  [*Note [1](#assign-note-1)*:
  variant<string, string> v;
v = "abc"; is ill-formed, as both alternative types have an equally viable constructor
for the argument[.](#assign-12.3.sentence-2)
 â *end note*]

[13](#assign-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6197)

*Effects*: 

- [(13.1)](#assign-13.1)

  If *this holds a Tj, assigns std​::​forward<T>(t) to
the value contained in *this[.](#assign-13.1.sentence-1)

- [(13.2)](#assign-13.2)

  Otherwise, if is_nothrow_constructible_v<Tj, T> ||!is_nothrow_move_constructible_v<Tj> is true,
equivalent to emplace<j>(std​::​forward<T>(t))[.](#assign-13.2.sentence-1)

- [(13.3)](#assign-13.3)

  Otherwise, equivalent to emplace<j>(Tj(std​::​forward<T>(t)))[.](#assign-13.3.sentence-1)

[14](#assign-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6211)

*Postconditions*: holds_alternative<Tj>(*this) is true, with Tj selected by the imaginary function overload resolution described above[.](#assign-14.sentence-1)

[15](#assign-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6216)

*Returns*: *this[.](#assign-15.sentence-1)

[16](#assign-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6220)

*Remarks*: The exception specification is equivalent to:is_nothrow_assignable_v<Tj&, T> && is_nothrow_constructible_v<Tj, T>

- [(16.1)](#assign-16.1)

  If an exception is thrown during the assignment of std​::​forward<T>(t) to the value contained in *this, the state of the contained value andt are as defined by the exception safety guarantee of the assignment
expression; valueless_by_exception() will be false[.](#assign-16.1.sentence-1)

- [(16.2)](#assign-16.2)

  If an exception is thrown during the initialization of the contained value,
the variant object is permitted to not hold a value[.](#assign-16.2.sentence-1)

#### [22.6.3.5](#mod) Modifiers [[variant.mod]](variant.mod)

[ð](#lib:emplace,variant)

`template<class T, class... Args> constexpr T& emplace(Args&&... args);
`

[1](#mod-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6244)

*Constraints*: is_constructible_v<T, Args...> is true, andT occurs exactly once in Types[.](#mod-1.sentence-1)

[2](#mod-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6249)

*Effects*: Equivalent to:return emplace<I>(std::forward<Args>(args)...); where I is the zero-based index of T in Types[.](#mod-2.sentence-1)

[ð](#lib:emplace,variant_)

`template<class T, class U, class... Args>
  constexpr T& emplace(initializer_list<U> il, Args&&... args);
`

[3](#mod-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6265)

*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true,
and T occurs exactly once in Types[.](#mod-3.sentence-1)

[4](#mod-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6270)

*Effects*: Equivalent to:return emplace<I>(il, std::forward<Args>(args)...); where I is the zero-based index of T in Types[.](#mod-4.sentence-1)

[ð](#lib:emplace,variant__)

`template<size_t I, class... Args>
  constexpr variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
`

[5](#mod-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6286)

*Mandates*: I < sizeof...(Types)[.](#mod-5.sentence-1)

[6](#mod-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6290)

*Constraints*: is_constructible_v<TI, Args...> is true[.](#mod-6.sentence-1)

[7](#mod-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6294)

*Effects*: Destroys the currently contained value if valueless_by_exception() is false[.](#mod-7.sentence-1)

Then direct-non-list-initializes the contained value of type TI with the arguments std​::​forward<Args>(args)...[.](#mod-7.sentence-2)

[8](#mod-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6301)

*Postconditions*: index() is I[.](#mod-8.sentence-1)

[9](#mod-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6305)

*Returns*: A reference to the new contained value[.](#mod-9.sentence-1)

[10](#mod-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6309)

*Throws*: Any exception thrown during the initialization of the contained value[.](#mod-10.sentence-1)

[11](#mod-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6313)

*Remarks*: If an exception is thrown during the initialization of the contained value,
the variant is permitted to not hold a value[.](#mod-11.sentence-1)

[ð](#lib:emplace,variant___)

`template<size_t I, class U, class... Args>
  constexpr variant_alternative_t<I, variant<Types...>>&
    emplace(initializer_list<U> il, Args&&... args);
`

[12](#mod-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6327)

*Mandates*: I < sizeof...(Types)[.](#mod-12.sentence-1)

[13](#mod-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6331)

*Constraints*: is_constructible_v<TI, initializer_list<U>&, Args...> is true[.](#mod-13.sentence-1)

[14](#mod-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6335)

*Effects*: Destroys the currently contained value if valueless_by_exception() is false[.](#mod-14.sentence-1)

Then direct-non-list-initializes the contained value of type TI with il, std​::​forward<Args>(args)...[.](#mod-14.sentence-2)

[15](#mod-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6342)

*Postconditions*: index() is I[.](#mod-15.sentence-1)

[16](#mod-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6346)

*Returns*: A reference to the new contained value[.](#mod-16.sentence-1)

[17](#mod-17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6350)

*Throws*: Any exception thrown during the initialization of the contained value[.](#mod-17.sentence-1)

[18](#mod-18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6354)

*Remarks*: If an exception is thrown during the initialization of the contained value,
the variant is permitted to not hold a value[.](#mod-18.sentence-1)

#### [22.6.3.6](#status) Value status [[variant.status]](variant.status)

[ð](#lib:valueless_by_exception,variant)

`constexpr bool valueless_by_exception() const noexcept;
`

[1](#status-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6368)

*Effects*: Returns false if and only if the variant holds a value[.](#status-1.sentence-1)

[2](#status-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6372)

[*Note [1](#status-note-1)*:

It is possible for a variant to hold no value
if an exception is thrown during a
type-changing assignment or emplacement[.](#status-2.sentence-1)

The latter means that even avariant<float, int> can become valueless_by_exception(), for
instance bystruct S { operator int() { throw 42; }};
variant<float, int> v{12.f};
v.emplace<1>(S());

â *end note*]

[ð](#lib:index,variant)

`constexpr size_t index() const noexcept;
`

[3](#status-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6393)

*Effects*: If valueless_by_exception() is true, returns variant_npos[.](#status-3.sentence-1)

Otherwise, returns the zero-based index of the alternative of the contained value[.](#status-3.sentence-2)

#### [22.6.3.7](#swap) Swap [[variant.swap]](variant.swap)

[ð](#lib:swap,variant)

`constexpr void swap(variant& rhs) noexcept(see below);
`

[1](#swap-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6407)

*Mandates*: is_move_constructible_v<Ti> is true for all i[.](#swap-1.sentence-1)

[2](#swap-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6411)

*Preconditions*: Each Ti meets the [*Cpp17Swappable*](swappable.requirements#:Cpp17Swappable "16.4.4.3 Swappable requirements [swappable.requirements]") requirements ([[swappable.requirements]](swappable.requirements "16.4.4.3 Swappable requirements"))[.](#swap-2.sentence-1)

[3](#swap-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6415)

*Effects*: 

- [(3.1)](#swap-3.1)

  If valueless_by_exception() && rhs.valueless_by_exception() no effect[.](#swap-3.1.sentence-1)

- [(3.2)](#swap-3.2)

  Otherwise, if index() == rhs.index(), calls swap(*GET*<i>(*this), *GET*<i>(rhs)) where i is index()[.](#swap-3.2.sentence-1)

- [(3.3)](#swap-3.3)

  Otherwise, exchanges values of rhs and *this[.](#swap-3.3.sentence-1)

[4](#swap-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6426)

*Throws*: If index() == rhs.index(),
any exception thrown by swap(*GET*<i>(*this), *GET*<i>(rhs)) with i being index()[.](#swap-4.sentence-1)

Otherwise, any exception thrown by the move constructor
of Ti or Tj with i being index() and j being rhs.index()[.](#swap-4.sentence-2)

[5](#swap-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6435)

*Remarks*: If an exception is thrown during the call to function swap(*GET*<i>(*this), *GET*<i>(rhs)),
the states of the contained values of *this and of rhs are
determined by the exception safety guarantee of swap for lvalues ofTi with i being index()[.](#swap-5.sentence-1)

If an exception is thrown during the exchange of the values of *this and rhs, the states of the values of *this and of rhs are determined by the exception safety guarantee of variant's move constructor[.](#swap-5.sentence-2)

The exception specification is equivalent to the logical and ofis_nothrow_move_constructible_v<Ti> && is_nothrow_swappable_v<Ti> for all i[.](#swap-5.sentence-3)

### [22.6.4](#helper) variant helper classes [[variant.helper]](variant.helper)

[ð](#lib:variant_size)

`template<class T> struct variant_size;
`

[1](#helper-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6456)

All specializations of variant_size meet the[*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements"))
with a base characteristic of integral_constant<size_t, N> for some N[.](#helper-1.sentence-1)

[ð](#lib:variant_size_)

`template<class T> struct variant_size<const T>;
`

[2](#helper-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6468)

Let VS denote variant_size<T> of the cv-unqualified
type T[.](#helper-2.sentence-1)

Then each specialization of the template meets the[*Cpp17UnaryTypeTrait*](meta.rqmts#:Cpp17UnaryTypeTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements")) with a
base characteristic of integral_constant<size_t, VS​::​value>[.](#helper-2.sentence-2)

[ð](#lib:variant_size__)

`template<class... Types>
  struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
`

[ð](#lib:variant_alternative)

`template<size_t I, class T> struct variant_alternative<I, const T>;
`

[3](#helper-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6488)

Let VA denote variant_alternative<I, T> of the
cv-unqualified type T[.](#helper-3.sentence-1)

Then each specialization of the template
meets the [*Cpp17TransformationTrait*](meta.rqmts#:Cpp17TransformationTrait "21.3.2 Requirements [meta.rqmts]") requirements ([[meta.rqmts]](meta.rqmts "21.3.2 Requirements")) with a
member typedef type that names the type add_const_t<VA​::​type>[.](#helper-3.sentence-2)

[ð](#lib:variant_alternative_)

`variant_alternative<I, variant<Types...>>::type
`

[4](#helper-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6501)

*Mandates*: I < sizeof...(Types)[.](#helper-4.sentence-1)

[5](#helper-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6505)

*Type*: The type TI[.](#helper-5.sentence-1)

### [22.6.5](#get) Value access [[variant.get]](variant.get)

[ð](#lib:holds_alternative)

`template<class T, class... Types>
  constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
`

[1](#get-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6520)

*Mandates*: The type T occurs exactly once in Types[.](#get-1.sentence-1)

[2](#get-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6524)

*Returns*: true if index() is equal to the zero-based index of T in Types[.](#get-2.sentence-1)

[ð](#get-itemdecl:2)

`template<size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>&
    GET(variant<Types...>& v);                                  // exposition only
template<size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>&&
    GET(variant<Types...>&& v);                                 // exposition only
template<size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>&
    GET(const variant<Types...>& v);                            // exposition only
template<size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>&&
    GET(const variant<Types...>&& v);                           // exposition only
`

[3](#get-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6545)

*Mandates*: I < sizeof...(Types)[.](#get-3.sentence-1)

[4](#get-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6549)

*Preconditions*: v.index() is I[.](#get-4.sentence-1)

[5](#get-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6553)

*Returns*: A reference to the object stored in the variant[.](#get-5.sentence-1)

[ð](#lib:get,variant)

`template<size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v);
template<size_t I, class... Types>
  constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v);
template<size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>& v);
template<size_t I, class... Types>
  constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&& v);
`

[6](#get-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6571)

*Mandates*: I < sizeof...(Types)[.](#get-6.sentence-1)

[7](#get-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6575)

*Effects*: If v.index() is I, returns a reference to the object stored in
the variant[.](#get-7.sentence-1)

Otherwise, throws an exception of type bad_variant_access[.](#get-7.sentence-2)

[ð](#lib:get,variant_)

`template<class T, class... Types> constexpr T& get(variant<Types...>& v);
template<class T, class... Types> constexpr T&& get(variant<Types...>&& v);
template<class T, class... Types> constexpr const T& get(const variant<Types...>& v);
template<class T, class... Types> constexpr const T&& get(const variant<Types...>&& v);
`

[8](#get-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6590)

*Mandates*: The type T occurs exactly once in Types[.](#get-8.sentence-1)

[9](#get-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6594)

*Effects*: If v holds a value of type T, returns a reference to that value[.](#get-9.sentence-1)

Otherwise, throws an exception of type bad_variant_access[.](#get-9.sentence-2)

[ð](#lib:get_if)

`template<size_t I, class... Types>
  constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
    get_if(variant<Types...>* v) noexcept;
template<size_t I, class... Types>
  constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
    get_if(const variant<Types...>* v) noexcept;
`

[10](#get-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6612)

*Mandates*: I < sizeof...(Types)[.](#get-10.sentence-1)

[11](#get-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6616)

*Returns*: A pointer to the value stored in the variant, if v != nullptr and v->index() == I[.](#get-11.sentence-1)

Otherwise, returns nullptr[.](#get-11.sentence-2)

[ð](#lib:get_if_)

`template<class T, class... Types>
  constexpr add_pointer_t<T>
    get_if(variant<Types...>* v) noexcept;
template<class T, class... Types>
  constexpr add_pointer_t<const T>
    get_if(const variant<Types...>* v) noexcept;
`

[12](#get-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6634)

*Mandates*: The type T occurs exactly once in Types[.](#get-12.sentence-1)

[13](#get-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6638)

*Effects*: Equivalent to: return get_if<i>(v); with i being the zero-based
index of T in Types[.](#get-13.sentence-1)

### [22.6.6](#relops) Relational operators [[variant.relops]](variant.relops)

[ð](#lib:operator==,variant)

`template<class... Types>
  constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
`

[1](#relops-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6653)

*Constraints*: *GET*<i>(v) == *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-1.sentence-1)

[2](#relops-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6658)

*Returns*: If v.index() != w.index(), false;
otherwise if v.valueless_by_exception(), true;
otherwise *GET*<i>(v) == *GET*<i>(w) with i being v.index()[.](#relops-2.sentence-1)

[ð](#lib:operator!=,variant)

`template<class... Types>
  constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
`

[3](#relops-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6672)

*Constraints*: *GET*<i>(v) != *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-3.sentence-1)

[4](#relops-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6677)

*Returns*: If v.index() != w.index(), true;
otherwise if v.valueless_by_exception(), false;
otherwise *GET*<i>(v) != *GET*<i>(w) with i being v.index()[.](#relops-4.sentence-1)

[ð](#lib:operator%3c,variant)

`template<class... Types>
  constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
`

[5](#relops-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6691)

*Constraints*: *GET*<i>(v) < *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-5.sentence-1)

[6](#relops-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6696)

*Returns*: If w.valueless_by_exception(), false;
otherwise if v.valueless_by_exception(), true;
otherwise, if v.index() < w.index(), true;
otherwise if v.index() > w.index(), false;
otherwise *GET*<i>(v) < *GET*<i>(w) with i being v.index()[.](#relops-6.sentence-1)

[ð](#lib:operator%3e,variant)

`template<class... Types>
  constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
`

[7](#relops-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6712)

*Constraints*: *GET*<i>(v) > *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-7.sentence-1)

[8](#relops-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6717)

*Returns*: If v.valueless_by_exception(), false;
otherwise if w.valueless_by_exception(), true;
otherwise, if v.index() > w.index(), true;
otherwise if v.index() < w.index(), false;
otherwise *GET*<i>(v) > *GET*<i>(w) with i being v.index()[.](#relops-8.sentence-1)

[ð](#lib:operator%3c=,variant)

`template<class... Types>
  constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
`

[9](#relops-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6733)

*Constraints*: *GET*<i>(v) <= *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-9.sentence-1)

[10](#relops-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6738)

*Returns*: If v.valueless_by_exception(), true;
otherwise if w.valueless_by_exception(), false;
otherwise, if v.index() < w.index(), true;
otherwise if v.index() > w.index(), false;
otherwise *GET*<i>(v) <= *GET*<i>(w) with i being v.index()[.](#relops-10.sentence-1)

[ð](#lib:operator%3e=,variant)

`template<class... Types>
  constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
`

[11](#relops-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6754)

*Constraints*: *GET*<i>(v) >= *GET*<i>(w) is a valid expression that is
convertible to bool, for all i[.](#relops-11.sentence-1)

[12](#relops-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6759)

*Returns*: If w.valueless_by_exception(), true;
otherwise if v.valueless_by_exception(), false;
otherwise, if v.index() > w.index(), true;
otherwise if v.index() < w.index(), false;
otherwise *GET*<i>(v) >= *GET*<i>(w) with i being v.index()[.](#relops-12.sentence-1)

[ð](#lib:operator%3c=%3e,variant)

`template<class... Types> requires ([three_way_comparable](cmp.concept#concept:three_way_comparable "17.12.4 Concept three_­way_­comparable [cmp.concept]")<Types> && ...)
  constexpr common_comparison_category_t<compare_three_way_result_t<Types>...>
    operator<=>(const variant<Types...>& v, const variant<Types...>& w);
`

[13](#relops-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6776)

*Effects*: Equivalent to:if (v.valueless_by_exception() && w.valueless_by_exception())return strong_ordering::equal;if (v.valueless_by_exception()) return strong_ordering::less;if (w.valueless_by_exception()) return strong_ordering::greater;if (auto c = v.index() <=> w.index(); c != 0) return c;return *GET*<i>(v) <=> *GET*<i>(w); with i being v.index()[.](#relops-13.sentence-1)

### [22.6.7](#visit) Visitation [[variant.visit]](variant.visit)

[ð](#lib:visit)

`template<class Visitor, class... Variants>
  constexpr see below visit(Visitor&& vis, Variants&&... vars);
template<class R, class Visitor, class... Variants>
  constexpr R visit(Visitor&& vis, Variants&&... vars);
`

[1](#visit-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6802)

Let *as-variant* denote the following exposition-only function templates:template<class... Ts>constexpr auto&& *as-variant*(variant<Ts...>& var) { return var; }template<class... Ts>constexpr auto&& *as-variant*(const variant<Ts...>& var) { return var; }template<class... Ts>constexpr auto&& *as-variant*(variant<Ts...>&& var) { return std::move(var); }template<class... Ts>constexpr auto&& *as-variant*(const variant<Ts...>&& var) { return std::move(var); }

Let n be sizeof...(Variants)[.](#visit-1.sentence-2)

For each 0â¤i<n, letVi denote the type  
decltype(*as-variant*(std​::​forward<Variantsi>(varsi)))[.](#visit-1.sentence-3)

[2](#visit-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6819)

*Constraints*: Vi is a valid type for all 0â¤i<n[.](#visit-2.sentence-1)

[3](#visit-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6823)

Let V denote the pack of types Vi[.](#visit-3.sentence-1)

[4](#visit-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6826)

Let m be a pack of n values of type size_t[.](#visit-4.sentence-1)

Such a pack is valid if  
0â¤mi<variant_size_v<remove_reference_t<Vi>> for all 0â¤i<n[.](#visit-4.sentence-2)

For each valid pack m, let e(m) denote the expression:*INVOKE*(std::forward<Visitor>(vis), *GET*<m>(std::forward<V>(vars))...) // see [[func.require]](func.require "22.10.4 Requirements") for the first form and*INVOKE*<R>(std::forward<Visitor>(vis), *GET*<m>(std::forward<V>(vars))...) // see [[func.require]](func.require "22.10.4 Requirements") for the second form[.](#visit-4.sentence-3)

[5](#visit-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6841)

*Mandates*: For each valid pack m, e(m) is a valid expression[.](#visit-5.sentence-1)

All such expressions are of the same type and value category[.](#visit-5.sentence-2)

[6](#visit-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6846)

*Returns*: e(m), where m is the pack for whichmi is *as-variant*(varsi).index() for all 0â¤i<n[.](#visit-6.sentence-1)

The return type is decltype(e(m)) for the first form[.](#visit-6.sentence-2)

[7](#visit-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6853)

*Throws*: bad_variant_access if(*as-variant*(vars).valueless_by_exception() || ...) is true[.](#visit-7.sentence-1)

[8](#visit-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6859)

*Complexity*: For n â¤ 1, the invocation of the callable object is
implemented in constant time, i.e., for n=1, it does not depend on
the number of alternative types of V0[.](#visit-8.sentence-1)

For n>1, the invocation of the callable object has
no complexity requirements[.](#visit-8.sentence-2)

[ð](#lib:visit,variant_)

`template<class Self, class Visitor>
  constexpr decltype(auto) visit(this Self&& self, Visitor&& vis);
`

[9](#visit-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6875)

Let V be*OVERRIDE_REF*(Self&&, *COPY_CONST*(remove_reference_t<Self>, variant)) ([[forward]](forward "22.2.4 Forward/move helpers"))[.](#visit-9.sentence-1)

[10](#visit-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6879)

*Constraints*: The call to visit does not use
an explicit [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") that
begins with a type [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#visit-10.sentence-1)

[11](#visit-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6885)

*Effects*: Equivalent to: return std​::​visit(std​::​forward<Visitor>(vis), (V)self);

[ð](#lib:visit,variant__)

`template<class R, class Self, class Visitor>
  constexpr R visit(this Self&& self, Visitor&& vis);
`

[12](#visit-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6897)

Let V be*OVERRIDE_REF*(Self&&, *COPY_CONST*(remove_reference_t<Self>, variant)) ([[forward]](forward "22.2.4 Forward/move helpers"))[.](#visit-12.sentence-1)

[13](#visit-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6901)

*Effects*: Equivalent to: return std​::​visit<R>(std​::​forward<Visitor>(vis), (V)self);

### [22.6.8](#monostate) Class monostate [[variant.monostate]](variant.monostate)

[ð](#lib:monostate_)

`struct monostate{};
`

[1](#monostate-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6915)

The class monostate can serve as a first alternative type for
a variant to make the variant type default constructible[.](#monostate-1.sentence-1)

### [22.6.9](#monostate.relops) monostate relational operators [[variant.monostate.relops]](variant.monostate.relops)

[ð](#lib:operator==,monostate)

`constexpr bool operator==(monostate, monostate) noexcept { return true; }
constexpr strong_ordering operator<=>(monostate, monostate) noexcept
{ return strong_ordering::equal; }
`

[1](#monostate.relops-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6932)

[*Note [1](#monostate.relops-note-1)*:

monostate objects have only a single state; they thus always compare equal[.](#monostate.relops-1.sentence-1)

â *end note*]

### [22.6.10](#specalg) Specialized algorithms [[variant.specalg]](variant.specalg)

[ð](#lib:swap,variant_)

`template<class... Types>
  constexpr void swap(variant<Types...>& v, variant<Types...>& w) noexcept(see below);
`

[1](#specalg-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6947)

*Constraints*: is_move_constructible_v<Ti> && is_swappable_v<Ti> is true for all i[.](#specalg-1.sentence-1)

[2](#specalg-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6952)

*Effects*: Equivalent to v.swap(w)[.](#specalg-2.sentence-1)

[3](#specalg-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6956)

*Remarks*: The exception specification is equivalent to noexcept(v.swap(w))[.](#specalg-3.sentence-1)

### [22.6.11](#bad.access) Class bad_variant_access [[variant.bad.access]](variant.bad.access)

namespace std {class bad_variant_access : public exception {public:// see [[exception]](exception "17.9.3 Class exception") for the specification of the special member functionsconstexpr const char* what() const noexcept override; };}

[1](#bad.access-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6974)

Objects of type bad_variant_access are thrown to report invalid
accesses to the value of a variant object[.](#bad.access-1.sentence-1)

[ð](#lib:what,bad_variant_access)

`constexpr const char* what() const noexcept override;
`

[2](#bad.access-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6984)

*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3 Character literals"))[.](#bad.access-2.sentence-1)

### [22.6.12](#hash) Hash support [[variant.hash]](variant.hash)

[ð](#lib:hash,variant)

`template<class... Types> struct hash<variant<Types...>>;
`

[1](#hash-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6999)

The specialization hash<variant<Types...>> is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash"))
if and only if every specialization in hash<remove_const_t<Types>>... is enabled[.](#hash-1.sentence-1)

The member functions are not guaranteed to be noexcept[.](#hash-1.sentence-2)

[ð](#lib:hash,monostate)

`template<> struct hash<monostate>;
`

[2](#hash-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7011)

The specialization is enabled ([[unord.hash]](unord.hash "22.10.19 Class template hash"))[.](#hash-2.sentence-1)
