[variant.assign] # 22 General utilities library [[utilities]](./#utilities) ## 22.6 Variants [[variant]](variant#assign) ### 22.6.3 Class template variant [[variant.variant]](variant.variant#variant.assign) #### 22.6.3.4 Assignment [variant.assign] [🔗](#lib:operator=,variant) `constexpr variant& operator=(const variant& rhs); ` [1](#1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6062) Let j be rhs.index()[.](#1.sentence-1) [2](#2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6065) *Effects*: - [(2.1)](#2.1) If neither *this nor rhs holds a value, there is no effect[.](#2.1.sentence-1) - [(2.2)](#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[.](#2.2.sentence-1) - [(2.3)](#2.3) Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this[.](#2.3.sentence-1) - [(2.4)](#2.4) Otherwise, if either is_nothrow_copy_constructible_v is true oris_nothrow_move_constructible_v is false, equivalent to emplace(*GET*(rhs))[.](#2.4.sentence-1) - [(2.5)](#2.5) Otherwise, equivalent to operator=(variant(rhs))[.](#2.5.sentence-1) [3](#3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6085) *Postconditions*: index() == rhs.index()[.](#3.sentence-1) [4](#4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6089) *Returns*: *this[.](#4.sentence-1) [5](#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[.](#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[.](#5.sentence-2) [🔗](#lib:operator=,variant_) `constexpr variant& operator=(variant&& rhs) noexcept(see below); ` [6](#6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6111) Let j be rhs.index()[.](#6.sentence-1) [7](#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[.](#7.sentence-1) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6120) *Effects*: - [(8.1)](#8.1) If neither *this nor rhs holds a value, there is no effect[.](#8.1.sentence-1) - [(8.2)](#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[.](#8.2.sentence-1) - [(8.3)](#8.3) Otherwise, if index() == j, assigns *GET*(std​::​move(rhs)) to the value contained in *this[.](#8.3.sentence-1) - [(8.4)](#8.4) Otherwise, equivalent to emplace(*GET*(std​::​move(rhs)))[.](#8.4.sentence-1) [9](#9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6135) *Returns*: *this[.](#9.sentence-1) [10](#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[.](#10.sentence-1) The exception specification is equivalent tois_nothrow_move_constructible_v && is_nothrow_move_assignable_v for all i[.](#10.sentence-2) - [(10.1)](#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[.](#10.1.sentence-1) - [(10.2)](#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[.](#10.2.sentence-1) [🔗](#lib:operator=,variant__) `template constexpr variant& operator=(T&& t) noexcept(see below); ` [11](#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[.](#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[.](#11.sentence-2) [12](#12) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6173) *Constraints*: - [(12.1)](#12.1) is_same_v, variant> is false, - [(12.2)](#12.2) is_assignable_v && is_constructible_v is true, and - [(12.3)](#12.3) the expression *FUN*(std​::​forward(t)) (with *FUN* being the above-mentioned set of imaginary functions) is well-formed[.](#12.sentence-1) [*Note [1](#note-1)*: variant v; v = "abc"; is ill-formed, as both alternative types have an equally viable constructor for the argument[.](#12.3.sentence-2) — *end note*] [13](#13) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6197) *Effects*: - [(13.1)](#13.1) If *this holds a Tj, assigns std​::​forward(t) to the value contained in *this[.](#13.1.sentence-1) - [(13.2)](#13.2) Otherwise, if is_nothrow_constructible_v ||!is_nothrow_move_constructible_v is true, equivalent to emplace(std​::​forward(t))[.](#13.2.sentence-1) - [(13.3)](#13.3) Otherwise, equivalent to emplace(Tj(std​::​forward(t)))[.](#13.3.sentence-1) [14](#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[.](#14.sentence-1) [15](#15) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L6216) *Returns*: *this[.](#15.sentence-1) [16](#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)](#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[.](#16.1.sentence-1) - [(16.2)](#16.2) If an exception is thrown during the initialization of the contained value, the variant object is permitted to not hold a value[.](#16.2.sentence-1)