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

Effects:

- If neither *this nor rhs holds a value, there is no effect.
- Otherwise, if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
- Otherwise, if index() == j, assigns the value contained in rhs to the value contained in *this.
- Otherwise, if either is_nothrow_copy_constructible_v<> is true or is_nothrow_move_constructible_v<> is false, equivalent to emplace<j>(get<j>(rhs)).
- Otherwise, equivalent to operator=(variant(rhs)).

Remarks: This operator is defined as deleted unless
is_copy_constructible_v<> &&
is_copy_assignable_v<>
is true for all i.

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.

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

Effects:

- If neither *this nor rhs holds a value, there is no effect.
- Otherwise, if *this holds a value but rhs does not, destroys the value contained in *this and sets *this to not hold a value.
- Otherwise, if index() == j, assigns get<j>(std::move(rhs)) to the value contained in *this.
- Otherwise, equivalent to emplace<j>(get<j>(std::move(rhs))).

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.

The expression inside noexcept is equivalent to:
is_nothrow_move_constructible_v<> && is_nothrow_move_assignable_v<> for all i.

- If an exception is thrown during the call to 's move construction (with j being rhs.index()), the variant will hold no value.
- If an exception is thrown during the call to 's move assignment, the state of the contained value is as defined by the exception safety guarantee of 's move assignment; index() will be j.

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

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

The overload FUN() selected by overload
resolution for the expression FUN(std::forward<T>(t)) defines
the alternative which is the type of the contained value after
assignment.

Constraints:

- is_same_v<remove_cvref_t<T>, variant> is false,
- is_assignable_v<&, T> && is_constructible_v<, T> is true, and
- the expression FUN(std::forward<T>(t))
(with FUN being the above-mentioned set
of imaginary functions) is well-formed. [Note:]
variant<string, string> v; v = "abc";

is ill-formed, as both alternative types have an equally viable constructor for the argument. â€”*end note*

Effects:

- If *this holds a , assigns std::forward<T>(t) to the value contained in *this.
- Otherwise, if is_nothrow_constructible_v<, T> || !is_nothrow_move_constructible_v<> is true, equivalent to emplace<j>(std::forward<T>(t)).
- Otherwise, equivalent to operator=(variant(std::forward<T>(t))).

Remarks: The expression inside noexcept is equivalent to:

is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>

- 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 and t are as defined by the exception safety guarantee of the assignment expression; valueless_by_exception() will be false.
- If an exception is thrown during the initialization of the contained value, the variant object might not hold a value.