[variant.variant] # 22 General utilities library [[utilities]](./#utilities) ## 22.6 Variants [[variant]](variant#variant) ### 22.6.3 Class template variant [variant.variant] #### [22.6.3.1](#general) General [[variant.variant.general]](variant.variant.general) namespace std {templateclass variant {public:// [[variant.ctor]](#variant.ctor "22.6.3.2 Constructors"), constructorsconstexpr variant() noexcept(*see below*); constexpr variant(const variant&); constexpr variant(variant&&) noexcept(*see below*); templateconstexpr variant(T&&) noexcept(*see below*); templateconstexpr explicit variant(in_place_type_t, Args&&...); templateconstexpr explicit variant(in_place_type_t, initializer_list, Args&&...); templateconstexpr explicit variant(in_place_index_t, Args&&...); templateconstexpr explicit variant(in_place_index_t, initializer_list, Args&&...); // [[variant.dtor]](#variant.dtor "22.6.3.3 Destructor"), destructorconstexpr ~variant(); // [[variant.assign]](#variant.assign "22.6.3.4 Assignment"), assignmentconstexpr variant& operator=(const variant&); constexpr variant& operator=(variant&&) noexcept(*see below*); template constexpr variant& operator=(T&&) noexcept(*see below*); // [[variant.mod]](#variant.mod "22.6.3.5 Modifiers"), modifierstemplateconstexpr T& emplace(Args&&...); templateconstexpr T& emplace(initializer_list, Args&&...); templateconstexpr variant_alternative_t>& emplace(Args&&...); templateconstexpr variant_alternative_t>& emplace(initializer_list, Args&&...); // [[variant.status]](#variant.status "22.6.3.6 Value status"), value statusconstexpr bool valueless_by_exception() const noexcept; constexpr size_t index() const noexcept; // [[variant.swap]](#variant.swap "22.6.3.7 Swap"), swapconstexpr void swap(variant&) noexcept(*see below*); // [[variant.visit]](variant.visit "22.6.7 Visitation"), visitationtemplateconstexpr decltype(auto) visit(this Self&&, Visitor&&); templateconstexpr R visit(this Self&&, Visitor&&); };} [1](#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[.](#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[.](#general-1.sentence-2) [2](#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"))[.](#general-2.sentence-1) [3](#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[.](#general-3.sentence-1) [4](#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[.](#general-4.sentence-1) #### [22.6.3.2](#variant.ctor) Constructors [[variant.ctor]](variant.ctor) [1](#variant.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[.](#variant.ctor-1.sentence-1) [🔗](#lib:variant,constructor) `constexpr variant() noexcept(see below); ` [2](#variant.ctor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5755) *Constraints*: is_default_constructible_v is true[.](#variant.ctor-2.sentence-1) [3](#variant.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[.](#variant.ctor-3.sentence-1) [4](#variant.ctor-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5763) *Postconditions*: valueless_by_exception() is false and index() is 0[.](#variant.ctor-4.sentence-1) [5](#variant.ctor-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5767) *Throws*: Any exception thrown by the value-initialization of T0[.](#variant.ctor-5.sentence-1) [6](#variant.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"))[.](#variant.ctor-6.sentence-1) The exception specification is equivalent tois_nothrow_default_constructible_v[.](#variant.ctor-6.sentence-2) [*Note [1](#variant.ctor-note-1)*: See also class monostate[.](#variant.ctor-6.sentence-3) — *end note*] [🔗](#lib:variant,constructor_) `constexpr variant(const variant& w); ` [7](#variant.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*(w), where j is w.index()[.](#variant.ctor-7.sentence-1) Otherwise, initializes the variant to not hold a value[.](#variant.ctor-7.sentence-2) [8](#variant.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[.](#variant.ctor-8.sentence-1) [9](#variant.ctor-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5800) *Remarks*: This constructor is defined as deleted unlessis_copy_constructible_v is true for all i[.](#variant.ctor-9.sentence-1) If is_trivially_copy_constructible_v is true for all i, this constructor is trivial[.](#variant.ctor-9.sentence-2) [🔗](#lib:variant,constructor__) `constexpr variant(variant&& w) noexcept(see below); ` [10](#variant.ctor-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5814) *Constraints*: is_move_constructible_v is true for all i[.](#variant.ctor-10.sentence-1) [11](#variant.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*(std​::​move(w)), where j is w.index()[.](#variant.ctor-11.sentence-1) Otherwise, initializes the variant to not hold a value[.](#variant.ctor-11.sentence-2) [12](#variant.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[.](#variant.ctor-12.sentence-1) [13](#variant.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 for all i[.](#variant.ctor-13.sentence-1) If is_trivially_move_constructible_v is true for all i, this constructor is trivial[.](#variant.ctor-13.sentence-2) [🔗](#lib:variant,constructor___) `template constexpr variant(T&& t) noexcept(see below); ` [14](#variant.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)}; is well-formed for some invented variable x[.](#variant.ctor-14.sentence-1) The overload *FUN*(Tj) selected by overload resolution for the expression *FUN*(std​::​forward(​t)) defines the alternative Tj which is the type of the contained value after construction[.](#variant.ctor-14.sentence-2) [15](#variant.ctor-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5854) *Constraints*: - [(15.1)](#variant.ctor-15.1) sizeof...(Types) is nonzero, - [(15.2)](#variant.ctor-15.2) is_same_v, variant> is false, - [(15.3)](#variant.ctor-15.3) remove_cvref_t is neither a specialization of in_place_type_t nor a specialization of in_place_index_t, - [(15.4)](#variant.ctor-15.4) is_constructible_v is true, and - [(15.5)](#variant.ctor-15.5) the expression *FUN*(​std​::​forward(t)) (with *FUN* being the above-mentioned set of imaginary functions) is well-formed[.](#variant.ctor-15.sentence-1) [*Note [2](#variant.ctor-note-2)*: variant v("abc"); is ill-formed, as both alternative types have an equally viable constructor for the argument[.](#variant.ctor-15.5.sentence-2) — *end note*] [16](#variant.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)[.](#variant.ctor-16.sentence-1) [17](#variant.ctor-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5889) *Postconditions*: holds_alternative(*this) is true[.](#variant.ctor-17.sentence-1) [18](#variant.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[.](#variant.ctor-18.sentence-1) [19](#variant.ctor-19) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5897) *Remarks*: The exception specification is equivalent tois_nothrow_constructible_v[.](#variant.ctor-19.sentence-1) If Tj's selected constructor is a constexpr constructor, this constructor is a constexpr constructor[.](#variant.ctor-19.sentence-2) [🔗](#lib:variant,constructor____) `template constexpr explicit variant(in_place_type_t, Args&&... args); ` [20](#variant.ctor-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5911) *Constraints*: - [(20.1)](#variant.ctor-20.1) There is exactly one occurrence of T in Types... and - [(20.2)](#variant.ctor-20.2) is_constructible_v is true[.](#variant.ctor-20.sentence-1) [21](#variant.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)...[.](#variant.ctor-21.sentence-1) [22](#variant.ctor-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5923) *Postconditions*: holds_alternative(*this) is true[.](#variant.ctor-22.sentence-1) [23](#variant.ctor-23) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5927) *Throws*: Any exception thrown by calling the selected constructor of T[.](#variant.ctor-23.sentence-1) [24](#variant.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[.](#variant.ctor-24.sentence-1) [🔗](#lib:variant,constructor_____) `template constexpr explicit variant(in_place_type_t, initializer_list il, Args&&... args); ` [25](#variant.ctor-25) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5944) *Constraints*: - [(25.1)](#variant.ctor-25.1) There is exactly one occurrence of T in Types... and - [(25.2)](#variant.ctor-25.2) is_constructible_v&, Args...> is true[.](#variant.ctor-25.sentence-1) [26](#variant.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)...[.](#variant.ctor-26.sentence-1) [27](#variant.ctor-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5956) *Postconditions*: holds_alternative(*this) is true[.](#variant.ctor-27.sentence-1) [28](#variant.ctor-28) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5960) *Throws*: Any exception thrown by calling the selected constructor of T[.](#variant.ctor-28.sentence-1) [29](#variant.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[.](#variant.ctor-29.sentence-1) [🔗](#lib:variant,constructor______) `template constexpr explicit variant(in_place_index_t, Args&&... args); ` [30](#variant.ctor-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5976) *Constraints*: - [(30.1)](#variant.ctor-30.1) I is less than sizeof...(Types) and - [(30.2)](#variant.ctor-30.2) is_constructible_v is true[.](#variant.ctor-30.sentence-1) [31](#variant.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)...[.](#variant.ctor-31.sentence-1) [32](#variant.ctor-32) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5990) *Postconditions*: index() is I[.](#variant.ctor-32.sentence-1) [33](#variant.ctor-33) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L5994) *Throws*: Any exception thrown by calling the selected constructor of TI[.](#variant.ctor-33.sentence-1) [34](#variant.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[.](#variant.ctor-34.sentence-1) [🔗](#lib:variant,constructor_______) `template constexpr explicit variant(in_place_index_t, initializer_list il, Args&&... args); ` [35](#variant.ctor-35) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6011) *Constraints*: - [(35.1)](#variant.ctor-35.1) I is less than sizeof...(Types) and - [(35.2)](#variant.ctor-35.2) is_constructible_v&, Args...> is true[.](#variant.ctor-35.sentence-1) [36](#variant.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)...[.](#variant.ctor-36.sentence-1) [37](#variant.ctor-37) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6025) *Postconditions*: index() is I[.](#variant.ctor-37.sentence-1) [38](#variant.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[.](#variant.ctor-38.sentence-1) #### [22.6.3.3](#variant.dtor) Destructor [[variant.dtor]](variant.dtor) [🔗](#lib:variant,destructor) `constexpr ~variant(); ` [1](#variant.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[.](#variant.dtor-1.sentence-1) [2](#variant.dtor-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6048) *Remarks*: If is_trivially_destructible_v is true for all Ti, then this destructor is trivial[.](#variant.dtor-2.sentence-1) #### [22.6.3.4](#variant.assign) Assignment [[variant.assign]](variant.assign) [🔗](#lib:operator=,variant) `constexpr variant& operator=(const variant& rhs); ` [1](#variant.assign-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6062) Let j be rhs.index()[.](#variant.assign-1.sentence-1) [2](#variant.assign-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6065) *Effects*: - [(2.1)](#variant.assign-2.1) If neither *this nor rhs holds a value, there is no effect[.](#variant.assign-2.1.sentence-1) - [(2.2)](#variant.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[.](#variant.assign-2.2.sentence-1) - [(2.3)](#variant.assign-2.3) Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this[.](#variant.assign-2.3.sentence-1) - [(2.4)](#variant.assign-2.4) Otherwise, if either is_nothrow_copy_constructible_v is true oris_nothrow_move_constructible_v is false, equivalent to emplace(*GET*(rhs))[.](#variant.assign-2.4.sentence-1) - [(2.5)](#variant.assign-2.5) Otherwise, equivalent to operator=(variant(rhs))[.](#variant.assign-2.5.sentence-1) [3](#variant.assign-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6085) *Postconditions*: index() == rhs.index()[.](#variant.assign-3.sentence-1) [4](#variant.assign-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6089) *Returns*: *this[.](#variant.assign-4.sentence-1) [5](#variant.assign-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6093) *Remarks*: This operator is defined as deleted unlessis_copy_constructible_v &&is_copy_assignable_v is true for all i[.](#variant.assign-5.sentence-1) If is_trivially_copy_constructible_v &&is_trivially_copy_assignable_v &&is_trivially_destructible_v is true for all i, this assignment operator is trivial[.](#variant.assign-5.sentence-2) [🔗](#lib:operator=,variant_) `constexpr variant& operator=(variant&& rhs) noexcept(see below); ` [6](#variant.assign-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6111) Let j be rhs.index()[.](#variant.assign-6.sentence-1) [7](#variant.assign-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6114) *Constraints*: is_move_constructible_v &&is_move_assignable_v istrue for all i[.](#variant.assign-7.sentence-1) [8](#variant.assign-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6120) *Effects*: - [(8.1)](#variant.assign-8.1) If neither *this nor rhs holds a value, there is no effect[.](#variant.assign-8.1.sentence-1) - [(8.2)](#variant.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[.](#variant.assign-8.2.sentence-1) - [(8.3)](#variant.assign-8.3) Otherwise, if index() == j, assigns *GET*(std​::​move(rhs)) to the value contained in *this[.](#variant.assign-8.3.sentence-1) - [(8.4)](#variant.assign-8.4) Otherwise, equivalent to emplace(*GET*(std​::​move(rhs)))[.](#variant.assign-8.4.sentence-1) [9](#variant.assign-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6135) *Returns*: *this[.](#variant.assign-9.sentence-1) [10](#variant.assign-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6139) *Remarks*: If is_trivially_move_constructible_v &&is_trivially_move_assignable_v &&is_trivially_destructible_v is true for all i, this assignment operator is trivial[.](#variant.assign-10.sentence-1) The exception specification is equivalent tois_nothrow_move_constructible_v && is_nothrow_move_assignable_v for all i[.](#variant.assign-10.sentence-2) - [(10.1)](#variant.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[.](#variant.assign-10.1.sentence-1) - [(10.2)](#variant.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[.](#variant.assign-10.2.sentence-1) [🔗](#lib:operator=,variant__) `template constexpr variant& operator=(T&& t) noexcept(see below); ` [11](#variant.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)}; is well-formed for some invented variable x[.](#variant.assign-11.sentence-1) The overload *FUN*(Tj) selected by overload resolution for the expression *FUN*(std​::​forward(​t)) defines the alternative Tj which is the type of the contained value after assignment[.](#variant.assign-11.sentence-2) [12](#variant.assign-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6173) *Constraints*: - [(12.1)](#variant.assign-12.1) is_same_v, variant> is false, - [(12.2)](#variant.assign-12.2) is_assignable_v && is_constructible_v is true, and - [(12.3)](#variant.assign-12.3) the expression *FUN*(std​::​forward(t)) (with *FUN* being the above-mentioned set of imaginary functions) is well-formed[.](#variant.assign-12.sentence-1) [*Note [1](#variant.assign-note-1)*: variant v; v = "abc"; is ill-formed, as both alternative types have an equally viable constructor for the argument[.](#variant.assign-12.3.sentence-2) — *end note*] [13](#variant.assign-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6197) *Effects*: - [(13.1)](#variant.assign-13.1) If *this holds a Tj, assigns std​::​forward(t) to the value contained in *this[.](#variant.assign-13.1.sentence-1) - [(13.2)](#variant.assign-13.2) Otherwise, if is_nothrow_constructible_v ||!is_nothrow_move_constructible_v is true, equivalent to emplace(std​::​forward(t))[.](#variant.assign-13.2.sentence-1) - [(13.3)](#variant.assign-13.3) Otherwise, equivalent to emplace(Tj(std​::​forward(t)))[.](#variant.assign-13.3.sentence-1) [14](#variant.assign-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6211) *Postconditions*: holds_alternative(*this) is true, with Tj selected by the imaginary function overload resolution described above[.](#variant.assign-14.sentence-1) [15](#variant.assign-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6216) *Returns*: *this[.](#variant.assign-15.sentence-1) [16](#variant.assign-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6220) *Remarks*: The exception specification is equivalent to:is_nothrow_assignable_v && is_nothrow_constructible_v - [(16.1)](#variant.assign-16.1) If an exception is thrown during the assignment of std​::​forward(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[.](#variant.assign-16.1.sentence-1) - [(16.2)](#variant.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[.](#variant.assign-16.2.sentence-1) #### [22.6.3.5](#variant.mod) Modifiers [[variant.mod]](variant.mod) [🔗](#lib:emplace,variant) `template constexpr T& emplace(Args&&... args); ` [1](#variant.mod-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6244) *Constraints*: is_constructible_v is true, andT occurs exactly once in Types[.](#variant.mod-1.sentence-1) [2](#variant.mod-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6249) *Effects*: Equivalent to:return emplace(std::forward(args)...); where I is the zero-based index of T in Types[.](#variant.mod-2.sentence-1) [🔗](#lib:emplace,variant_) `template constexpr T& emplace(initializer_list il, Args&&... args); ` [3](#variant.mod-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6265) *Constraints*: is_constructible_v&, Args...> is true, and T occurs exactly once in Types[.](#variant.mod-3.sentence-1) [4](#variant.mod-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6270) *Effects*: Equivalent to:return emplace(il, std::forward(args)...); where I is the zero-based index of T in Types[.](#variant.mod-4.sentence-1) [🔗](#lib:emplace,variant__) `template constexpr variant_alternative_t>& emplace(Args&&... args); ` [5](#variant.mod-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6286) *Mandates*: I < sizeof...(Types)[.](#variant.mod-5.sentence-1) [6](#variant.mod-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6290) *Constraints*: is_constructible_v is true[.](#variant.mod-6.sentence-1) [7](#variant.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[.](#variant.mod-7.sentence-1) Then direct-non-list-initializes the contained value of type TI with the arguments std​::​forward(args)...[.](#variant.mod-7.sentence-2) [8](#variant.mod-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6301) *Postconditions*: index() is I[.](#variant.mod-8.sentence-1) [9](#variant.mod-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6305) *Returns*: A reference to the new contained value[.](#variant.mod-9.sentence-1) [10](#variant.mod-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6309) *Throws*: Any exception thrown during the initialization of the contained value[.](#variant.mod-10.sentence-1) [11](#variant.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[.](#variant.mod-11.sentence-1) [🔗](#lib:emplace,variant___) `template constexpr variant_alternative_t>& emplace(initializer_list il, Args&&... args); ` [12](#variant.mod-12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6327) *Mandates*: I < sizeof...(Types)[.](#variant.mod-12.sentence-1) [13](#variant.mod-13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6331) *Constraints*: is_constructible_v&, Args...> is true[.](#variant.mod-13.sentence-1) [14](#variant.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[.](#variant.mod-14.sentence-1) Then direct-non-list-initializes the contained value of type TI with il, std​::​forward(args)...[.](#variant.mod-14.sentence-2) [15](#variant.mod-15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6342) *Postconditions*: index() is I[.](#variant.mod-15.sentence-1) [16](#variant.mod-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6346) *Returns*: A reference to the new contained value[.](#variant.mod-16.sentence-1) [17](#variant.mod-17) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6350) *Throws*: Any exception thrown during the initialization of the contained value[.](#variant.mod-17.sentence-1) [18](#variant.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[.](#variant.mod-18.sentence-1) #### [22.6.3.6](#variant.status) Value status [[variant.status]](variant.status) [🔗](#lib:valueless_by_exception,variant) `constexpr bool valueless_by_exception() const noexcept; ` [1](#variant.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[.](#variant.status-1.sentence-1) [2](#variant.status-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6372) [*Note [1](#variant.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[.](#variant.status-2.sentence-1) The latter means that even avariant can become valueless_by_exception(), for instance bystruct S { operator int() { throw 42; }}; variant v{12.f}; v.emplace<1>(S()); — *end note*] [🔗](#lib:index,variant) `constexpr size_t index() const noexcept; ` [3](#variant.status-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6393) *Effects*: If valueless_by_exception() is true, returns variant_npos[.](#variant.status-3.sentence-1) Otherwise, returns the zero-based index of the alternative of the contained value[.](#variant.status-3.sentence-2) #### [22.6.3.7](#variant.swap) Swap [[variant.swap]](variant.swap) [🔗](#lib:swap,variant) `constexpr void swap(variant& rhs) noexcept(see below); ` [1](#variant.swap-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6407) *Mandates*: is_move_constructible_v is true for all i[.](#variant.swap-1.sentence-1) [2](#variant.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"))[.](#variant.swap-2.sentence-1) [3](#variant.swap-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6415) *Effects*: - [(3.1)](#variant.swap-3.1) If valueless_by_exception() && rhs.valueless_by_exception() no effect[.](#variant.swap-3.1.sentence-1) - [(3.2)](#variant.swap-3.2) Otherwise, if index() == rhs.index(), calls swap(*GET*(*this), *GET*(rhs)) where i is index()[.](#variant.swap-3.2.sentence-1) - [(3.3)](#variant.swap-3.3) Otherwise, exchanges values of rhs and *this[.](#variant.swap-3.3.sentence-1) [4](#variant.swap-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6426) *Throws*: If index() == rhs.index(), any exception thrown by swap(*GET*(*this), *GET*(rhs)) with i being index()[.](#variant.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()[.](#variant.swap-4.sentence-2) [5](#variant.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*(*this), *GET*(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()[.](#variant.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[.](#variant.swap-5.sentence-2) The exception specification is equivalent to the logical and ofis_nothrow_move_constructible_v && is_nothrow_swappable_v for all i[.](#variant.swap-5.sentence-3)