[expected.object.assign]

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

## 22.8 Expected objects [[expected]](expected#object.assign)

### 22.8.6 Class template expected [[expected.expected]](expected.expected#expected.object.assign)

#### 22.8.6.4 Assignment [expected.object.assign]

[1](#1)

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

This subclause makes use of the following exposition-only function template:template<class T, class U, class... Args>constexpr void *reinit-expected*(T& newval, U& oldval, Args&&... args) { // *exposition only*if constexpr (is_nothrow_constructible_v<T, Args...>) { destroy_at(addressof(oldval));
 construct_at(addressof(newval), std::forward<Args>(args)...); } else if constexpr (is_nothrow_move_constructible_v<T>) { T tmp(std::forward<Args>(args)...);
 destroy_at(addressof(oldval));
 construct_at(addressof(newval), std::move(tmp)); } else { U tmp(std::move(oldval));
 destroy_at(addressof(oldval)); try { construct_at(addressof(newval), std::forward<Args>(args)...); } catch (...) { construct_at(addressof(oldval), std::move(tmp)); throw; }}}

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

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

[2](#2)

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

*Effects*: 

- [(2.1)](#2.1)

  If this->has_value() && rhs.has_value() is true,
equivalent to *val* = *rhs[.](#2.1.sentence-1)

- [(2.2)](#2.2)

  Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, rhs.error())

- [(2.3)](#2.3)

  Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, *rhs)

- [(2.4)](#2.4)

  Otherwise, equivalent to *unex* = rhs.error()[.](#2.4.sentence-1)

Then, if no exception was thrown,
equivalent to: *has_val* = rhs.has_value(); return *this;

[3](#3)

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

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

[4](#4)

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

*Remarks*: This operator is defined as deleted unless:

- [(4.1)](#4.1)

is_copy_assignable_v<T> is true and

- [(4.2)](#4.2)

is_copy_constructible_v<T> is true and

- [(4.3)](#4.3)

is_copy_assignable_v<E> is true and

- [(4.4)](#4.4)

is_copy_constructible_v<E> is true and

- [(4.5)](#4.5)

is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#4.sentence-1)

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

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

[5](#5)

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

*Constraints*: 

- [(5.1)](#5.1)

is_move_constructible_v<T> is true and

- [(5.2)](#5.2)

is_move_assignable_v<T> is true and

- [(5.3)](#5.3)

is_move_constructible_v<E> is true and

- [(5.4)](#5.4)

is_move_assignable_v<E> is true and

- [(5.5)](#5.5)

is_nothrow_move_constructible_v<T> || is_nothrow_move_constructible_v<E> is true[.](#5.sentence-1)

[6](#6)

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

*Effects*: 

- [(6.1)](#6.1)

  If this->has_value() && rhs.has_value() is true,
equivalent to *val* = std​::​move(*rhs)[.](#6.1.sentence-1)

- [(6.2)](#6.2)

  Otherwise, if this->has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::move(rhs.error()))

- [(6.3)](#6.3)

  Otherwise, if rhs.has_value() is true, equivalent to:*reinit-expected*(*val*, *unex*, std::move(*rhs))

- [(6.4)](#6.4)

  Otherwise, equivalent to *unex* = std​::​move(rhs.error())[.](#6.4.sentence-1)

Then, if no exception was thrown,
equivalent to: has_val = rhs.has_value(); return *this;

[7](#7)

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

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

[8](#8)

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

*Remarks*: The exception specification is equivalent to:is_nothrow_move_assignable_v<T> && is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<E> && is_nothrow_move_constructible_v<E>

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

`template<class U = remove_cv_t<T>>
  constexpr expected& operator=(U&& v);
`

[9](#9)

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

*Constraints*: 

- [(9.1)](#9.1)

is_same_v<expected, remove_cvref_t<U>> is false; and

- [(9.2)](#9.2)

remove_cvref_t<U> is not a specialization of unexpected; and

- [(9.3)](#9.3)

is_constructible_v<T, U> is true; and

- [(9.4)](#9.4)

is_assignable_v<T&, U> is true; and

- [(9.5)](#9.5)

is_nothrow_constructible_v<T, U> || is_nothrow_move_constructible_v<T> ||  
is_nothrow_move_constructible_v<E> is true[.](#9.sentence-1)

[10](#10)

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

*Effects*: 

- [(10.1)](#10.1)

If has_value() is true,
equivalent to: *val* = std​::​forward<U>(v);

- [(10.2)](#10.2)

Otherwise, equivalent to:*reinit-expected*(*val*, *unex*, std::forward<U>(v));*has_val* = true;

[11](#11)

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

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

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

`template<class G>
  constexpr expected& operator=(const unexpected<G>& e);
template<class G>
  constexpr expected& operator=(unexpected<G>&& e);
`

[12](#12)

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

Let GF be const G& for the first overload andG for the second overload[.](#12.sentence-1)

[13](#13)

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

*Constraints*: 

- [(13.1)](#13.1)

is_constructible_v<E, GF> is true; and

- [(13.2)](#13.2)

is_assignable_v<E&, GF> is true; and

- [(13.3)](#13.3)

is_nothrow_constructible_v<E, GF> || is_nothrow_move_constructible_v<T> ||  
is_nothrow_move_constructible_v<E> is true[.](#13.sentence-1)

[14](#14)

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

*Effects*: 

- [(14.1)](#14.1)

If has_value() is true, equivalent to:*reinit-expected*(*unex*, *val*, std::forward<GF>(e.error()));*has_val* = false;

- [(14.2)](#14.2)

Otherwise, equivalent to:*unex* = std​::​forward<GF>(e.error());

[15](#15)

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

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

[ð](#lib:emplace,expected)

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

[16](#16)

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

*Constraints*: is_nothrow_constructible_v<T, Args...> is true[.](#16.sentence-1)

[17](#17)

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

*Effects*: Equivalent to:if (has_value()) { destroy_at(addressof(*val*));} else { destroy_at(addressof(*unex*)); *has_val* = true;}return *construct_at(addressof(*val*), std::forward<Args>(args)...);

[ð](#lib:emplace,expected_)

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

[18](#18)

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

*Constraints*: is_nothrow_constructible_v<T, initializer_list<U>&, Args...> is true[.](#18.sentence-1)

[19](#19)

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

*Effects*: Equivalent to:if (has_value()) { destroy_at(addressof(*val*));} else { destroy_at(addressof(*unex*)); *has_val* = true;}return *construct_at(addressof(*val*), il, std::forward<Args>(args)...);
