[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<Tj> is true oris_nothrow_move_constructible_v<Tj> is false,
equivalent to emplace<j>(*GET*<j>(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<Ti> &&is_copy_assignable_v<Ti> is true for all i[.](#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[.](#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<Ti> &&is_move_assignable_v<Ti> 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*<j>(std​::​move(rhs)) to
the value contained in *this[.](#8.3.sentence-1)

- [(8.4)](#8.4)

  Otherwise, equivalent to emplace<j>(*GET*<j>(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<Ti> &&is_trivially_move_assignable_v<Ti> &&is_trivially_destructible_v<Ti> is true for all i, this assignment operator is trivial[.](#10.sentence-1)

The exception specification is equivalent tois_nothrow_move_constructible_v<Ti> && is_nothrow_move_assignable_v<Ti> 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<class T> 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>(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>(​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<remove_cvref_t<T>, variant> is false,

- [(12.2)](#12.2)

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

- [(12.3)](#12.3)

the expression *FUN*(std​::​forward<T>(t)) (with *FUN* being the above-mentioned set
of imaginary functions) is well-formed[.](#12.sentence-1)
  [*Note [1](#note-1)*:
  variant<string, string> 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>(t) to
the value contained in *this[.](#13.1.sentence-1)

- [(13.2)](#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))[.](#13.2.sentence-1)

- [(13.3)](#13.3)

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

[14](#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[.](#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<Tj&, T> && is_nothrow_constructible_v<Tj, T>

- [(16.1)](#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[.](#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)
