[expected]

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

## 22.8 Expected objects [expected]

### [22.8.1](#general) General [[expected.general]](expected.general)

[1](#general-1)

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

Subclause [expected] describes the class template expected that represents expected objects[.](#general-1.sentence-1)

An expected<T, E> object holds
an object of type T or an object of type E and
manages the lifetime of the contained objects[.](#general-1.sentence-2)

### [22.8.2](#syn) Header <expected> synopsis [[expected.syn]](expected.syn)

[ð](#header:%3cexpected%3e)

// mostly freestandingnamespace std {// [[expected.unexpected]](#unexpected "22.8.3 Class template unexpected"), class template unexpectedtemplate<class E> class unexpected; // [[expected.bad]](#bad "22.8.4 Class template bad_­expected_­access"), class template bad_expected_accesstemplate<class E> class bad_expected_access; // [[expected.bad.void]](#bad.void "22.8.5 Class template specialization bad_­expected_­access<void>"), specialization for voidtemplate<> class bad_expected_access<void>; // in-place construction of unexpected valuesstruct unexpect_t {explicit unexpect_t() = default; }; inline constexpr unexpect_t unexpect{}; // [[expected.expected]](#expected "22.8.6 Class template expected"), class template expectedtemplate<class T, class E> class expected; // partially freestanding// [[expected.void]](#void "22.8.7 Partial specialization of expected for void types"), partial specialization of expected for void typestemplate<class T, class E> requires is_void_v<T> class expected<T, E>; // partially freestanding}

### [22.8.3](#unexpected) Class template unexpected [[expected.unexpected]](expected.unexpected)

#### [22.8.3.1](#un.general) General [[expected.un.general]](expected.un.general)

[1](#un.general-1)

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

Subclause [[expected.unexpected]](#unexpected "22.8.3 Class template unexpected") describes the class template unexpected that represents unexpected objects stored in expected objects[.](#un.general-1.sentence-1)

[ð](#lib:unexpected)

namespace std {template<class E>class unexpected {public:// [[expected.un.cons]](#un.cons "22.8.3.2 Constructors"), constructorsconstexpr unexpected(const unexpected&) = default; constexpr unexpected(unexpected&&) = default; template<class Err = E>constexpr explicit unexpected(Err&&); template<class... Args>constexpr explicit unexpected(in_place_t, Args&&...); template<class U, class... Args>constexpr explicit unexpected(in_place_t, initializer_list<U>, Args&&...); constexpr unexpected& operator=(const unexpected&) = default; constexpr unexpected& operator=(unexpected&&) = default; constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; constexpr void swap(unexpected& other) noexcept(*see below*); template<class E2>friend constexpr bool operator==(const unexpected&, const unexpected<E2>&); friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y))); private: E *unex*; // *exposition only*}; template<class E> unexpected(E) -> unexpected<E>;}

[2](#un.general-2)

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

A program that instantiates the definition of unexpected for
a non-object type,
an array type,
a specialization of unexpected, or
a cv-qualified type
is ill-formed[.](#un.general-2.sentence-1)

#### [22.8.3.2](#un.cons) Constructors [[expected.un.cons]](expected.un.cons)

[ð](#lib:unexpected,constructor)

`template<class Err = E>
  constexpr explicit unexpected(Err&& e);
`

[1](#un.cons-1)

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

*Constraints*: 

- [(1.1)](#un.cons-1.1)

is_same_v<remove_cvref_t<Err>, unexpected> is false; and

- [(1.2)](#un.cons-1.2)

is_same_v<remove_cvref_t<Err>, in_place_t> is false; and

- [(1.3)](#un.cons-1.3)

is_constructible_v<E, Err> is true[.](#un.cons-1.sentence-1)

[2](#un.cons-2)

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

*Effects*: Direct-non-list-initializes *unex* with std​::​forward<Err>(e)[.](#un.cons-2.sentence-1)

[3](#un.cons-3)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-3.sentence-1)

[ð](#lib:unexpected,constructor_)

`template<class... Args>
  constexpr explicit unexpected(in_place_t, Args&&... args);
`

[4](#un.cons-4)

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

*Constraints*: is_constructible_v<E, Args...> is true[.](#un.cons-4.sentence-1)

[5](#un.cons-5)

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

*Effects*: Direct-non-list-initializes*unex* with std​::​forward<Args>(args)...[.](#un.cons-5.sentence-1)

[6](#un.cons-6)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-6.sentence-1)

[ð](#lib:unexpected,constructor__)

`template<class U, class... Args>
  constexpr explicit unexpected(in_place_t, initializer_list<U> il, Args&&... args);
`

[7](#un.cons-7)

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

*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#un.cons-7.sentence-1)

[8](#un.cons-8)

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

*Effects*: Direct-non-list-initializes*unex* with il, std​::​forward<Args>(args)...[.](#un.cons-8.sentence-1)

[9](#un.cons-9)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#un.cons-9.sentence-1)

#### [22.8.3.3](#un.obs) Observers [[expected.un.obs]](expected.un.obs)

[ð](#lib:error,unexpected)

`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`

[1](#un.obs-1)

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

*Returns*: *unex*[.](#un.obs-1.sentence-1)

[ð](#lib:error,unexpected_)

`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`

[2](#un.obs-2)

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

*Returns*: std​::​move(*unex*)[.](#un.obs-2.sentence-1)

#### [22.8.3.4](#un.swap) Swap [[expected.un.swap]](expected.un.swap)

[ð](#lib:swap,unexpected)

`constexpr void swap(unexpected& other) noexcept(is_nothrow_swappable_v<E>);
`

[1](#un.swap-1)

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

*Mandates*: is_swappable_v<E> is true[.](#un.swap-1.sentence-1)

[2](#un.swap-2)

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

*Effects*: Equivalent to:using std​::​swap; swap(*unex*, other.*unex*);

[ð](#un.swap-itemdecl:2)

`friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
`

[3](#un.swap-3)

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

*Constraints*: is_swappable_v<E> is true[.](#un.swap-3.sentence-1)

[4](#un.swap-4)

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

*Effects*: Equivalent to x.swap(y)[.](#un.swap-4.sentence-1)

#### [22.8.3.5](#un.eq) Equality operator [[expected.un.eq]](expected.un.eq)

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

`template<class E2>
  friend constexpr bool operator==(const unexpected& x, const unexpected<E2>& y);
`

[1](#un.eq-1)

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

*Mandates*: The expression x.error() == y.error() is well-formed and
its result is convertible to bool[.](#un.eq-1.sentence-1)

[2](#un.eq-2)

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

*Returns*: x.error() == y.error()[.](#un.eq-2.sentence-1)

### [22.8.4](#bad) Class template bad_expected_access [[expected.bad]](expected.bad)

[ð](#lib:bad_expected_access)

namespace std {template<class E>class bad_expected_access : public bad_expected_access<void> {public:constexpr explicit bad_expected_access(E); constexpr const char* what() const noexcept override; constexpr E& error() & noexcept; constexpr const E& error() const & noexcept; constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept; private: E *unex*; // *exposition only*};}

[1](#bad-1)

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

The class template bad_expected_access defines the type of objects thrown as exceptions to report the situation
where an attempt is made to access the value of an expected<T, E> object
for which has_value() is false[.](#bad-1.sentence-1)

[ð](#lib:bad_expected_access,constructor)

`constexpr explicit bad_expected_access(E e);
`

[2](#bad-2)

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

*Effects*: Initializes *unex* with std​::​move(e)[.](#bad-2.sentence-1)

[ð](#lib:error,bad_expected_access)

`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`

[3](#bad-3)

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

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

[ð](#lib:error,bad_expected_access_)

`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`

[4](#bad-4)

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

*Returns*: std​::​move(*unex*)[.](#bad-4.sentence-1)

[ð](#lib:what,bad_expected_access)

`constexpr const char* what() const noexcept override;
`

[5](#bad-5)

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

*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3 Character literals"))[.](#bad-5.sentence-1)

### [22.8.5](#bad.void) Class template specialization bad_expected_access<void> [[expected.bad.void]](expected.bad.void)

namespace std {template<>class bad_expected_access<void> : public exception {protected:constexpr bad_expected_access() noexcept; constexpr bad_expected_access(const bad_expected_access&) noexcept; constexpr bad_expected_access(bad_expected_access&&) noexcept; constexpr bad_expected_access& operator=(const bad_expected_access&) noexcept; constexpr bad_expected_access& operator=(bad_expected_access&&) noexcept; constexpr ~bad_expected_access(); public:constexpr const char* what() const noexcept override; };}

[ð](#lib:what,bad_expected_access_)

`constexpr const char* what() const noexcept override;
`

[1](#bad.void-1)

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

*Returns*: An implementation-defined ntbs,
which during constant evaluation is encoded with
the ordinary literal encoding ([[lex.ccon]](lex.ccon "5.13.3 Character literals"))[.](#bad.void-1.sentence-1)

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

#### [22.8.6.1](#object.general) General [[expected.object.general]](expected.object.general)

namespace std {template<class T, class E>class expected {public:using [value_type](#lib:expected,value_type "22.8.6.1 General [expected.object.general]") = T; using [error_type](#lib:expected,error_type "22.8.6.1 General [expected.object.general]") = E; using [unexpected_type](#lib:expected,unexpected_type "22.8.6.1 General [expected.object.general]") = unexpected<E>; template<class U>using [rebind](#lib:expected,rebind "22.8.6.1 General [expected.object.general]") = expected<U, error_type>; // [[expected.object.cons]](#object.cons "22.8.6.2 Constructors"), constructorsconstexpr expected(); constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); template<class U, class G>constexpr explicit(*see below*) expected(const expected<U, G>&); template<class U, class G>constexpr explicit(*see below*) expected(expected<U, G>&&); template<class U = remove_cv_t<T>>constexpr explicit(*see below*) expected(U&& v); template<class G>constexpr explicit(*see below*) expected(const unexpected<G>&); template<class G>constexpr explicit(*see below*) expected(unexpected<G>&&); template<class... Args>constexpr explicit expected(in_place_t, Args&&...); template<class U, class... Args>constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...); template<class... Args>constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args>constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [[expected.object.dtor]](#object.dtor "22.8.6.3 Destructor"), destructorconstexpr ~expected(); // [[expected.object.assign]](#object.assign "22.8.6.4 Assignment"), assignmentconstexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(*see below*); template<class U = remove_cv_t<T>> constexpr expected& operator=(U&&); template<class G>constexpr expected& operator=(const unexpected<G>&); template<class G>constexpr expected& operator=(unexpected<G>&&); template<class... Args>constexpr T& emplace(Args&&...) noexcept; template<class U, class... Args>constexpr T& emplace(initializer_list<U>, Args&&...) noexcept; // [[expected.object.swap]](#object.swap "22.8.6.5 Swap"), swapconstexpr void swap(expected&) noexcept(*see below*); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [[expected.object.obs]](#object.obs "22.8.6.6 Observers"), observersconstexpr const T* operator->() const noexcept; constexpr T* operator->() noexcept; constexpr const T& operator*() const & noexcept; constexpr T& operator*() & noexcept; constexpr const T&& operator*() const && noexcept; constexpr T&& operator*() && noexcept; constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr const T& value() const &; // freestanding-deletedconstexpr T& value() &; // freestanding-deletedconstexpr const T&& value() const &&; // freestanding-deletedconstexpr T&& value() &&; // freestanding-deletedconstexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) const &; template<class U = remove_cv_t<T>> constexpr T value_or(U&&) &&; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [[expected.object.monadic]](#object.monadic "22.8.6.7 Monadic operations"), monadic operationstemplate<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [[expected.object.eq]](#object.eq "22.8.6.8 Equality operators"), equality operatorstemplate<class T2, class E2> requires (!is_void_v<T2>)friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class T2>friend constexpr bool operator==(const expected&, const T2&); template<class E2>friend constexpr bool operator==(const expected&, const unexpected<E2>&); private:bool *has_val*; // *exposition only*union { T *val*; // *exposition only* E *unex*; // *exposition only*}; };}

[1](#object.general-1)

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

Any object of type expected<T, E> either
contains a value of type T or
a value of type E nested within ([[intro.object]](intro.object "6.8.2 Object model")) it[.](#object.general-1.sentence-1)

Member *has_val* indicates whether the expected<T, E> object
contains an object of type T[.](#object.general-1.sentence-2)

[2](#object.general-2)

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

A type T is a [*valid value type for expected*](#def:valid_value_type_for_expected),
if remove_cv_t<T> is void or a complete non-array object type that is not in_place_t,unexpect_t,
or a specialization of unexpected[.](#object.general-2.sentence-1)

A program which instantiates class template expected<T, E> with an argument T that is not a valid value
type for expected is ill-formed[.](#object.general-2.sentence-2)

A program that instantiates
the definition of the template expected<T, E> with a type for the E parameter
that is not a valid template argument for unexpected is ill-formed[.](#object.general-2.sentence-3)

[3](#object.general-3)

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

When T is not cv void, it 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"))[.](#object.general-3.sentence-1)

E shall meet
the [*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") requirements[.](#object.general-3.sentence-2)

#### [22.8.6.2](#object.cons) Constructors [[expected.object.cons]](expected.object.cons)

[1](#object.cons-1)

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

The exposition-only variable template *converts-from-any-cvref* defined in [[optional.ctor]](optional.ctor "22.5.3.2 Constructors") is used by some constructors for expected[.](#object.cons-1.sentence-1)

[ð](#lib:expected,constructor)

`constexpr expected();
`

[2](#object.cons-2)

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

*Constraints*: is_default_constructible_v<T> is true[.](#object.cons-2.sentence-1)

[3](#object.cons-3)

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

*Effects*: Value-initializes *val*[.](#object.cons-3.sentence-1)

[4](#object.cons-4)

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

*Postconditions*: has_value() is true[.](#object.cons-4.sentence-1)

[5](#object.cons-5)

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

*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-5.sentence-1)

[ð](#lib:expected,constructor_)

`constexpr expected(const expected& rhs);
`

[6](#object.cons-6)

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

*Effects*: If rhs.has_value() is true,
direct-non-list-initializes *val* with *rhs[.](#object.cons-6.sentence-1)

Otherwise, direct-non-list-initializes *unex* with rhs.error()[.](#object.cons-6.sentence-2)

[7](#object.cons-7)

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

*Postconditions*: rhs.has_value() == this->has_value()[.](#object.cons-7.sentence-1)

[8](#object.cons-8)

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

*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-8.sentence-1)

[9](#object.cons-9)

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

*Remarks*: This constructor is defined as deleted unless

- [(9.1)](#object.cons-9.1)

is_copy_constructible_v<T> is true and

- [(9.2)](#object.cons-9.2)

is_copy_constructible_v<E> is true[.](#object.cons-9.sentence-1)

[10](#object.cons-10)

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

This constructor is trivial if

- [(10.1)](#object.cons-10.1)

is_trivially_copy_constructible_v<T> is true and

- [(10.2)](#object.cons-10.2)

is_trivially_copy_constructible_v<E> is true[.](#object.cons-10.sentence-1)

[ð](#lib:expected,constructor__)

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

[11](#object.cons-11)

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

*Constraints*: 

- [(11.1)](#object.cons-11.1)

is_move_constructible_v<T> is true and

- [(11.2)](#object.cons-11.2)

is_move_constructible_v<E> is true[.](#object.cons-11.sentence-1)

[12](#object.cons-12)

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

*Effects*: If rhs.has_value() is true,
direct-non-list-initializes *val* with std​::​move(*rhs)[.](#object.cons-12.sentence-1)

Otherwise,
direct-non-list-initializes *unex* with std​::​move(rhs.error())[.](#object.cons-12.sentence-2)

[13](#object.cons-13)

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

*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#object.cons-13.sentence-1)

[14](#object.cons-14)

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

*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-14.sentence-1)

[15](#object.cons-15)

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

*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<T> && is_nothrow_move_constructible_v<E>[.](#object.cons-15.sentence-1)

[16](#object.cons-16)

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

This constructor is trivial if

- [(16.1)](#object.cons-16.1)

is_trivially_move_constructible_v<T> is true and

- [(16.2)](#object.cons-16.2)

is_trivially_move_constructible_v<E> is true[.](#object.cons-16.sentence-1)

[ð](#lib:expected,constructor___)

`template<class U, class G>
  constexpr explicit(see below) expected(const expected<U, G>& rhs);
template<class U, class G>
  constexpr explicit(see below) expected(expected<U, G>&& rhs);
`

[17](#object.cons-17)

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

Let:

- [(17.1)](#object.cons-17.1)

  UF be const U& for the first overload andU for the second overload[.](#object.cons-17.1.sentence-1)

- [(17.2)](#object.cons-17.2)

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

[18](#object.cons-18)

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

*Constraints*: 

- [(18.1)](#object.cons-18.1)

is_constructible_v<T, UF> is true; and

- [(18.2)](#object.cons-18.2)

is_constructible_v<E, GF> is true; and

- [(18.3)](#object.cons-18.3)

if T is not cv bool,*converts-from-any-cvref*<T, expected<U, G>> is false; and

- [(18.4)](#object.cons-18.4)

is_constructible_v<unexpected<E>, expected<U, G>&> is false; and

- [(18.5)](#object.cons-18.5)

is_constructible_v<unexpected<E>, expected<U, G>> is false; and

- [(18.6)](#object.cons-18.6)

is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and

- [(18.7)](#object.cons-18.7)

is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#object.cons-18.sentence-1)

[19](#object.cons-19)

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

*Effects*: If rhs.has_value(),
direct-non-list-initializes *val* with std​::​forward<UF>(*rhs)[.](#object.cons-19.sentence-1)

Otherwise,
direct-non-list-initializes *unex* with std​::​forward<GF>(rhs.error())[.](#object.cons-19.sentence-2)

[20](#object.cons-20)

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

*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#object.cons-20.sentence-1)

[21](#object.cons-21)

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

*Throws*: Any exception thrown by the initialization of *val* or *unex*[.](#object.cons-21.sentence-1)

[22](#object.cons-22)

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

*Remarks*: The expression inside explicit is equivalent to!is_convertible_v<UF, T> || !is_convertible_v<GF, E>[.](#object.cons-22.sentence-1)

[ð](#lib:expected,constructor____)

`template<class U = remove_cv_t<T>>
  constexpr explicit(!is_convertible_v<U, T>) expected(U&& v);
`

[23](#object.cons-23)

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

*Constraints*: 

- [(23.1)](#object.cons-23.1)

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

- [(23.2)](#object.cons-23.2)

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

- [(23.3)](#object.cons-23.3)

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

- [(23.4)](#object.cons-23.4)

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

- [(23.5)](#object.cons-23.5)

is_constructible_v<T, U> is true; and

- [(23.6)](#object.cons-23.6)

if T is cv bool,remove_cvref_t<U> is not a specialization of expected[.](#object.cons-23.sentence-1)

[24](#object.cons-24)

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

*Effects*: Direct-non-list-initializes *val* with std​::​forward<U>(v)[.](#object.cons-24.sentence-1)

[25](#object.cons-25)

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

*Postconditions*: has_value() is true[.](#object.cons-25.sentence-1)

[26](#object.cons-26)

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

*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-26.sentence-1)

[ð](#lib:expected,constructor_____)

`template<class G>
  constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
template<class G>
  constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
`

[27](#object.cons-27)

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

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

[28](#object.cons-28)

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

*Constraints*: is_constructible_v<E, GF> is true[.](#object.cons-28.sentence-1)

[29](#object.cons-29)

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

*Effects*: Direct-non-list-initializes *unex* with std​::​forward<GF>(e.error())[.](#object.cons-29.sentence-1)

[30](#object.cons-30)

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

*Postconditions*: has_value() is false[.](#object.cons-30.sentence-1)

[31](#object.cons-31)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-31.sentence-1)

[ð](#lib:expected,constructor______)

`template<class... Args>
  constexpr explicit expected(in_place_t, Args&&... args);
`

[32](#object.cons-32)

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

*Constraints*: is_constructible_v<T, Args...> is true[.](#object.cons-32.sentence-1)

[33](#object.cons-33)

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

*Effects*: Direct-non-list-initializes *val* with std​::​forward<Args>(args)...[.](#object.cons-33.sentence-1)

[34](#object.cons-34)

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

*Postconditions*: has_value() is true[.](#object.cons-34.sentence-1)

[35](#object.cons-35)

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

*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-35.sentence-1)

[ð](#lib:expected,constructor_______)

`template<class U, class... Args>
  constexpr explicit expected(in_place_t, initializer_list<U> il, Args&&... args);
`

[36](#object.cons-36)

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

*Constraints*: is_constructible_v<T, initializer_list<U>&, Args...> is true[.](#object.cons-36.sentence-1)

[37](#object.cons-37)

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

*Effects*: Direct-non-list-initializes *val* withil, std​::​forward<Args>(args)...[.](#object.cons-37.sentence-1)

[38](#object.cons-38)

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

*Postconditions*: has_value() is true[.](#object.cons-38.sentence-1)

[39](#object.cons-39)

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

*Throws*: Any exception thrown by the initialization of *val*[.](#object.cons-39.sentence-1)

[ð](#lib:expected,constructor________)

`template<class... Args>
  constexpr explicit expected(unexpect_t, Args&&... args);
`

[40](#object.cons-40)

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

*Constraints*: is_constructible_v<E, Args...> is true[.](#object.cons-40.sentence-1)

[41](#object.cons-41)

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

*Effects*: Direct-non-list-initializes *unex* withstd​::​forward<Args>(args)...[.](#object.cons-41.sentence-1)

[42](#object.cons-42)

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

*Postconditions*: has_value() is false[.](#object.cons-42.sentence-1)

[43](#object.cons-43)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-43.sentence-1)

[ð](#lib:expected,constructor_________)

`template<class U, class... Args>
  constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
`

[44](#object.cons-44)

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

*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#object.cons-44.sentence-1)

[45](#object.cons-45)

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

*Effects*: Direct-non-list-initializes *unex* withil, std​::​forward<Args>(args)...[.](#object.cons-45.sentence-1)

[46](#object.cons-46)

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

*Postconditions*: has_value() is false[.](#object.cons-46.sentence-1)

[47](#object.cons-47)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#object.cons-47.sentence-1)

#### [22.8.6.3](#object.dtor) Destructor [[expected.object.dtor]](expected.object.dtor)

[ð](#lib:expected,destructor)

`constexpr ~expected();
`

[1](#object.dtor-1)

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

*Effects*: If has_value() is true, destroys *val*,
otherwise destroys *unex*[.](#object.dtor-1.sentence-1)

[2](#object.dtor-2)

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

*Remarks*: If is_trivially_destructible_v<T> is true, andis_trivially_destructible_v<E> is true,
then this destructor is a trivial destructor[.](#object.dtor-2.sentence-1)

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

[1](#object.assign-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](#object.assign-2)

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

*Effects*: 

- [(2.1)](#object.assign-2.1)

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

- [(2.2)](#object.assign-2.2)

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

- [(2.3)](#object.assign-2.3)

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

- [(2.4)](#object.assign-2.4)

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

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

[3](#object.assign-3)

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

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

[4](#object.assign-4)

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

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

- [(4.1)](#object.assign-4.1)

is_copy_assignable_v<T> is true and

- [(4.2)](#object.assign-4.2)

is_copy_constructible_v<T> is true and

- [(4.3)](#object.assign-4.3)

is_copy_assignable_v<E> is true and

- [(4.4)](#object.assign-4.4)

is_copy_constructible_v<E> is true and

- [(4.5)](#object.assign-4.5)

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

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

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

[5](#object.assign-5)

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

*Constraints*: 

- [(5.1)](#object.assign-5.1)

is_move_constructible_v<T> is true and

- [(5.2)](#object.assign-5.2)

is_move_assignable_v<T> is true and

- [(5.3)](#object.assign-5.3)

is_move_constructible_v<E> is true and

- [(5.4)](#object.assign-5.4)

is_move_assignable_v<E> is true and

- [(5.5)](#object.assign-5.5)

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

[6](#object.assign-6)

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

*Effects*: 

- [(6.1)](#object.assign-6.1)

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

- [(6.2)](#object.assign-6.2)

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

- [(6.3)](#object.assign-6.3)

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

- [(6.4)](#object.assign-6.4)

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

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

[7](#object.assign-7)

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

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

[8](#object.assign-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](#object.assign-9)

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

*Constraints*: 

- [(9.1)](#object.assign-9.1)

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

- [(9.2)](#object.assign-9.2)

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

- [(9.3)](#object.assign-9.3)

is_constructible_v<T, U> is true; and

- [(9.4)](#object.assign-9.4)

is_assignable_v<T&, U> is true; and

- [(9.5)](#object.assign-9.5)

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

[10](#object.assign-10)

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

*Effects*: 

- [(10.1)](#object.assign-10.1)

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

- [(10.2)](#object.assign-10.2)

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

[11](#object.assign-11)

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

*Returns*: *this[.](#object.assign-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](#object.assign-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[.](#object.assign-12.sentence-1)

[13](#object.assign-13)

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

*Constraints*: 

- [(13.1)](#object.assign-13.1)

is_constructible_v<E, GF> is true; and

- [(13.2)](#object.assign-13.2)

is_assignable_v<E&, GF> is true; and

- [(13.3)](#object.assign-13.3)

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

[14](#object.assign-14)

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

*Effects*: 

- [(14.1)](#object.assign-14.1)

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

- [(14.2)](#object.assign-14.2)

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

[15](#object.assign-15)

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

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

[ð](#lib:emplace,expected)

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

[16](#object.assign-16)

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

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

[17](#object.assign-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](#object.assign-18)

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

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

[19](#object.assign-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)...);

#### [22.8.6.5](#object.swap) Swap [[expected.object.swap]](expected.object.swap)

[ð](#lib:swap,expected)

`constexpr void swap(expected& rhs) noexcept(see below);
`

[1](#object.swap-1)

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

*Constraints*: 

- [(1.1)](#object.swap-1.1)

is_swappable_v<T> is true and

- [(1.2)](#object.swap-1.2)

is_swappable_v<E> is true and

- [(1.3)](#object.swap-1.3)

is_move_constructible_v<T> && is_move_constructible_v<E> is true, and

- [(1.4)](#object.swap-1.4)

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

[2](#object.swap-2)

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

*Effects*: See Table [72](#tab:expected.object.swap "Table 72: swap(expected&amp;) effects")[.](#object.swap-2.sentence-1)

Table [72](#tab:expected.object.swap) — swap(expected&) effects [[tab:expected.object.swap]](./tab:expected.object.swap)  

| [ð](#tab:expected.object.swap-row-1) | **this->has_value()** | **!this->has_value()** |
| --- | --- | --- |
| [ð](#tab:expected.object.swap-row-2)<br>**rhs.has_value()** | equivalent to: using std​::​swap; swap(*val*, rhs.*val*); | calls rhs.swap(*this) |
| [ð](#tab:expected.object.swap-row-3)<br>**!rhs.has_value()** | *see below* | equivalent to: using std​::​swap; swap(*unex*, rhs.*unex*); |

For the case where rhs.has_value() is false andthis->has_value() is true, equivalent to:if constexpr (is_nothrow_move_constructible_v<E>) { E tmp(std::move(rhs.*unex*));
 destroy_at(addressof(rhs.*unex*)); try { construct_at(addressof(rhs.*val*), std::move(*val*));
 destroy_at(addressof(*val*));
 construct_at(addressof(*unex*), std::move(tmp)); } catch(...) { construct_at(addressof(rhs.*unex*), std::move(tmp)); throw; }} else { T tmp(std::move(*val*));
 destroy_at(addressof(*val*)); try { construct_at(addressof(*unex*), std::move(rhs.*unex*));
 destroy_at(addressof(rhs.*unex*));
 construct_at(addressof(rhs.*val*), std::move(tmp)); } catch (...) { construct_at(addressof(*val*), std::move(tmp)); throw; }}*has_val* = false;
rhs.*has_val* = true;

[3](#object.swap-3)

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

*Throws*: Any exception thrown by the expressions in the *Effects*[.](#object.swap-3.sentence-1)

[4](#object.swap-4)

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

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

[ð](#lib:swap,expected_)

`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`

[5](#object.swap-5)

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

*Effects*: Equivalent to x.swap(y)[.](#object.swap-5.sentence-1)

#### [22.8.6.6](#object.obs) Observers [[expected.object.obs]](expected.object.obs)

[ð](#lib:operator-%3e,expected)

`constexpr const T* operator->() const noexcept;
constexpr T* operator->() noexcept;
`

[1](#object.obs-1)

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

*Hardened preconditions*: has_value() is true[.](#object.obs-1.sentence-1)

[2](#object.obs-2)

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

*Returns*: addressof(*val*)[.](#object.obs-2.sentence-1)

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

`constexpr const T& operator*() const & noexcept;
constexpr T& operator*() & noexcept;
`

[3](#object.obs-3)

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

*Hardened preconditions*: has_value() is true[.](#object.obs-3.sentence-1)

[4](#object.obs-4)

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

*Returns*: *val*[.](#object.obs-4.sentence-1)

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

`constexpr T&& operator*() && noexcept;
constexpr const T&& operator*() const && noexcept;
`

[5](#object.obs-5)

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

*Hardened preconditions*: has_value() is true[.](#object.obs-5.sentence-1)

[6](#object.obs-6)

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

*Returns*: std​::​move(*val*)[.](#object.obs-6.sentence-1)

[ð](#lib:operator_bool,expected)

`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`

[7](#object.obs-7)

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

*Returns*: *has_val*[.](#object.obs-7.sentence-1)

[ð](#lib:value,expected)

`constexpr const T& value() const &;
constexpr T& value() &;
`

[8](#object.obs-8)

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

*Mandates*: is_copy_constructible_v<E> is true[.](#object.obs-8.sentence-1)

[9](#object.obs-9)

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

*Returns*: *val*, if has_value() is true[.](#object.obs-9.sentence-1)

[10](#object.obs-10)

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

*Throws*: bad_expected_access(as_const(error())) if has_value() is false[.](#object.obs-10.sentence-1)

[ð](#lib:value,expected_)

`constexpr T&& value() &&;
constexpr const T&& value() const &&;
`

[11](#object.obs-11)

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

*Mandates*: is_copy_constructible_v<E> is true andis_constructible_v<E, decltype(std​::​move(error()))> is true[.](#object.obs-11.sentence-1)

[12](#object.obs-12)

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

*Returns*: std​::​move(*val*), if has_value() is true[.](#object.obs-12.sentence-1)

[13](#object.obs-13)

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

*Throws*: bad_expected_access(std​::​move(error())) if has_value() is false[.](#object.obs-13.sentence-1)

[ð](#lib:error,expected)

`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`

[14](#object.obs-14)

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

*Hardened preconditions*: has_value() is false[.](#object.obs-14.sentence-1)

[15](#object.obs-15)

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

*Returns*: *unex*[.](#object.obs-15.sentence-1)

[ð](#lib:error,expected_)

`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`

[16](#object.obs-16)

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

*Hardened preconditions*: has_value() is false[.](#object.obs-16.sentence-1)

[17](#object.obs-17)

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

*Returns*: std​::​move(*unex*)[.](#object.obs-17.sentence-1)

[ð](#lib:value_or,expected)

`template<class U = remove_cv_t<T>> constexpr T value_or(U&& v) const &;
`

[18](#object.obs-18)

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

*Mandates*: is_copy_constructible_v<T> is true andis_convertible_v<U, T> is true[.](#object.obs-18.sentence-1)

[19](#object.obs-19)

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

*Returns*: has_value() ? **this : static_cast<T>(std​::​forward<U>(v))[.](#object.obs-19.sentence-1)

[ð](#lib:value_or,expected_)

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

[20](#object.obs-20)

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

*Mandates*: is_move_constructible_v<T> is true andis_convertible_v<U, T> is true[.](#object.obs-20.sentence-1)

[21](#object.obs-21)

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

*Returns*: has_value() ? std​::​move(**this) : static_cast<T>(std​::​forward<U>(v))[.](#object.obs-21.sentence-1)

[ð](#lib:error_or,expected)

`template<class G = E> constexpr E error_or(G&& e) const &;
`

[22](#object.obs-22)

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

*Mandates*: is_copy_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#object.obs-22.sentence-1)

[23](#object.obs-23)

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

*Returns*: std​::​forward<G>(e) if has_value() is true,error() otherwise[.](#object.obs-23.sentence-1)

[ð](#lib:error_or,expected_)

`template<class G = E> constexpr E error_or(G&& e) &&;
`

[24](#object.obs-24)

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

*Mandates*: is_move_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#object.obs-24.sentence-1)

[25](#object.obs-25)

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

*Returns*: std​::​forward<G>(e) if has_value() is true,std​::​move(error()) otherwise[.](#object.obs-25.sentence-1)

#### [22.8.6.7](#object.monadic) Monadic operations [[expected.object.monadic]](expected.object.monadic)

[ð](#lib:and_then,expected)

`template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) const &;
`

[1](#object.monadic-1)

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

Let U be remove_cvref_t<invoke_result_t<F, decltype((*val*))>>[.](#object.monadic-1.sentence-1)

[2](#object.monadic-2)

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

*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#object.monadic-2.sentence-1)

[3](#object.monadic-3)

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

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#object.monadic-3.sentence-1)

[4](#object.monadic-4)

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

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f), *val*);elsereturn U(unexpect, error());

[ð](#lib:and_then,expected_)

`template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &&;
`

[5](#object.monadic-5)

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

Let U beremove_cvref_t<invoke_result_t<F, decltype(std​::​move(*val*))>>[.](#object.monadic-5.sentence-1)

[6](#object.monadic-6)

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

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#object.monadic-6.sentence-1)

[7](#object.monadic-7)

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

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#object.monadic-7.sentence-1)

[8](#object.monadic-8)

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

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f), std::move(*val*));elsereturn U(unexpect, std::move(error()));

[ð](#lib:or_else,expected)

`template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) const &;
`

[9](#object.monadic-9)

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

Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#object.monadic-9.sentence-1)

[10](#object.monadic-10)

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

*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#object.monadic-10.sentence-1)

[11](#object.monadic-11)

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

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#object.monadic-11.sentence-1)

[12](#object.monadic-12)

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

*Effects*: Equivalent to:if (has_value())return G(in_place, *val*);elsereturn invoke(std::forward<F>(f), error());

[ð](#lib:or_else,expected_)

`template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &&;
`

[13](#object.monadic-13)

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

Let G beremove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#object.monadic-13.sentence-1)

[14](#object.monadic-14)

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

*Constraints*: is_constructible_v<T, decltype(std​::​move(*val*))> is true[.](#object.monadic-14.sentence-1)

[15](#object.monadic-15)

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

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#object.monadic-15.sentence-1)

[16](#object.monadic-16)

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

*Effects*: Equivalent to:if (has_value())return G(in_place, std::move(*val*));elsereturn invoke(std::forward<F>(f), std::move(error()));

[ð](#lib:transform,expected)

`template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) const &;
`

[17](#object.monadic-17)

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

Let U beremove_cv_t<invoke_result_t<F, decltype((*val*))>>[.](#object.monadic-17.sentence-1)

[18](#object.monadic-18)

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

*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#object.monadic-18.sentence-1)

[19](#object.monadic-19)

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

*Mandates*: U is a valid value type for expected[.](#object.monadic-19.sentence-1)

If is_void_v<U> is false,
the declarationU u(invoke(std::forward<F>(f), *val*)); is well-formed[.](#object.monadic-19.sentence-2)

[20](#object.monadic-20)

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

*Effects*: 

- [(20.1)](#object.monadic-20.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#object.monadic-20.1.sentence-1)

- [(20.2)](#object.monadic-20.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), *val*)[.](#object.monadic-20.2.sentence-1)

- [(20.3)](#object.monadic-20.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f), *val*) and then
returns expected<U, E>()[.](#object.monadic-20.3.sentence-1)

[ð](#lib:transform,expected_)

`template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
`

[21](#object.monadic-21)

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

Let U beremove_cv_t<invoke_result_t<F, decltype(std​::​move(*val*))>>[.](#object.monadic-21.sentence-1)

[22](#object.monadic-22)

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

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#object.monadic-22.sentence-1)

[23](#object.monadic-23)

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

*Mandates*: U is a valid value type for expected[.](#object.monadic-23.sentence-1)

If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f), std::move(*val*))); is well-formed[.](#object.monadic-23.sentence-2)

[24](#object.monadic-24)

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

*Effects*: 

- [(24.1)](#object.monadic-24.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, std​::​move(error()))[.](#object.monadic-24.1.sentence-1)

- [(24.2)](#object.monadic-24.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), std​::​move(*val*))[.](#object.monadic-24.2.sentence-1)

- [(24.3)](#object.monadic-24.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f), std​::​move(*val*)) and
then returns expected<U, E>()[.](#object.monadic-24.3.sentence-1)

[ð](#lib:transform_error,expected)

`template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) const &;
`

[25](#object.monadic-25)

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

Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#object.monadic-25.sentence-1)

[26](#object.monadic-26)

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

*Constraints*: is_constructible_v<T, decltype((*val*))> is true[.](#object.monadic-26.sentence-1)

[27](#object.monadic-27)

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

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#object.monadic-27.sentence-1)

[28](#object.monadic-28)

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

*Returns*: If has_value() is true,expected<T, G>(in_place, *val*); otherwise, an expected<T, G> object whose *has_val* member is false and *unex* member
is direct-non-list-initialized with invoke(std​::​forward<F>(f), error())[.](#object.monadic-28.sentence-1)

[ð](#lib:transform_error,expected_)

`template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &&;
`

[29](#object.monadic-29)

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

Let G beremove_cv_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#object.monadic-29.sentence-1)

[30](#object.monadic-30)

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

*Constraints*: is_constructible_v<T, decltype(std​::​move(*val*))> is true[.](#object.monadic-30.sentence-1)

[31](#object.monadic-31)

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

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#object.monadic-31.sentence-1)

[32](#object.monadic-32)

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

*Returns*: If has_value() is true,expected<T, G>(in_place, std​::​move(*val*)); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), std​::​move(error()))[.](#object.monadic-32.sentence-1)

#### [22.8.6.8](#object.eq) Equality operators [[expected.object.eq]](expected.object.eq)

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

`template<class T2, class E2> requires (!is_void_v<T2>)
  friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
`

[1](#object.eq-1)

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

*Constraints*: The expressions *x == *y and x.error() == y.error() are well-formed and their results are convertible to bool[.](#object.eq-1.sentence-1)

[2](#object.eq-2)

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

*Returns*: If x.has_value() does not equal y.has_value(), false;
otherwise if x.has_value() is true, *x == *y;
otherwise x.error() == y.error()[.](#object.eq-2.sentence-1)

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

`template<class T2> friend constexpr bool operator==(const expected& x, const T2& v);
`

[3](#object.eq-3)

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

*Constraints*: T2 is not a specialization of expected[.](#object.eq-3.sentence-1)

The expression *x == v is well-formed and
its result is convertible to bool[.](#object.eq-3.sentence-2)

[*Note [1](#object.eq-note-1)*:

T need not be [*Cpp17EqualityComparable*](utility.arg.requirements#:Cpp17EqualityComparable "16.4.4.2 Template argument requirements [utility.arg.requirements]")[.](#object.eq-3.sentence-3)

â *end note*]

[4](#object.eq-4)

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

*Returns*: x.has_value() && static_cast<bool>(*x == v)[.](#object.eq-4.sentence-1)

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

`template<class E2> friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`

[5](#object.eq-5)

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

*Constraints*: The expression x.error() == e.error() is well-formed and
its result is convertible to bool[.](#object.eq-5.sentence-1)

[6](#object.eq-6)

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

*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#object.eq-6.sentence-1)

### [22.8.7](#void) Partial specialization of expected for void types [[expected.void]](expected.void)

#### [22.8.7.1](#void.general) General [[expected.void.general]](expected.void.general)

template<class T, class E> requires is_void_v<T>class expected<T, E> {public:using [value_type](#lib:expected%3cvoid%3e,value_type "22.8.7.1 General [expected.void.general]") = T; using [error_type](#lib:expected%3cvoid%3e,error_type "22.8.7.1 General [expected.void.general]") = E; using [unexpected_type](#lib:expected%3cvoid%3e,unexpected_type "22.8.7.1 General [expected.void.general]") = unexpected<E>; template<class U>using [rebind](#lib:expected%3cvoid%3e,rebind "22.8.7.1 General [expected.void.general]") = expected<U, error_type>; // [[expected.void.cons]](#void.cons "22.8.7.2 Constructors"), constructorsconstexpr expected() noexcept; constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); template<class U, class G>constexpr explicit(*see below*) expected(const expected<U, G>&); template<class U, class G>constexpr explicit(*see below*) expected(expected<U, G>&&); template<class G>constexpr explicit(*see below*) expected(const unexpected<G>&); template<class G>constexpr explicit(*see below*) expected(unexpected<G>&&); constexpr explicit expected(in_place_t) noexcept; template<class... Args>constexpr explicit expected(unexpect_t, Args&&...); template<class U, class... Args>constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...); // [[expected.void.dtor]](#void.dtor "22.8.7.3 Destructor"), destructorconstexpr ~expected(); // [[expected.void.assign]](#void.assign "22.8.7.4 Assignment"), assignmentconstexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(*see below*); template<class G>constexpr expected& operator=(const unexpected<G>&); template<class G>constexpr expected& operator=(unexpected<G>&&); constexpr void emplace() noexcept; // [[expected.void.swap]](#void.swap "22.8.7.5 Swap"), swapconstexpr void swap(expected&) noexcept(*see below*); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y))); // [[expected.void.obs]](#void.obs "22.8.7.6 Observers"), observersconstexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr void operator*() const noexcept; constexpr void value() const &; // freestanding-deletedconstexpr void value() &&; // freestanding-deletedconstexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; // [[expected.void.monadic]](#void.monadic "22.8.7.7 Monadic operations"), monadic operationstemplate<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; // [[expected.void.eq]](#void.eq "22.8.7.8 Equality operators"), equality operatorstemplate<class T2, class E2> requires is_void_v<T2>friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y); template<class E2>friend constexpr bool operator==(const expected&, const unexpected<E2>&);

private:bool *has_val*; // *exposition only*union { E *unex*; // *exposition only*};};

[1](#void.general-1)

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

Any object of type expected<T, E> either
represents a value of type T, or
contains a value of type E nested within ([[intro.object]](intro.object "6.8.2 Object model")) it[.](#void.general-1.sentence-1)

Member *has_val* indicates whether the expected<T, E> object
represents a value of type T[.](#void.general-1.sentence-2)

[2](#void.general-2)

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

A program that instantiates
the definition of the template expected<T, E> with
a type for the E parameter that
is not a valid template argument for unexpected is ill-formed[.](#void.general-2.sentence-1)

[3](#void.general-3)

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

E shall meet the requirements of[*Cpp17Destructible*](utility.arg.requirements#:Cpp17Destructible "16.4.4.2 Template argument requirements [utility.arg.requirements]") (Table [35](utility.arg.requirements#tab:cpp17.destructible "Table 35: Cpp17Destructible requirements"))[.](#void.general-3.sentence-1)

#### [22.8.7.2](#void.cons) Constructors [[expected.void.cons]](expected.void.cons)

[ð](#lib:expected%3cvoid%3e,constructor)

`constexpr expected() noexcept;
`

[1](#void.cons-1)

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

*Postconditions*: has_value() is true[.](#void.cons-1.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor_)

`constexpr expected(const expected& rhs);
`

[2](#void.cons-2)

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

*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with rhs.error()[.](#void.cons-2.sentence-1)

[3](#void.cons-3)

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

*Postconditions*: rhs.has_value() == this->has_value()[.](#void.cons-3.sentence-1)

[4](#void.cons-4)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-4.sentence-1)

[5](#void.cons-5)

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

*Remarks*: This constructor is defined as deleted
unless is_copy_constructible_v<E> is true[.](#void.cons-5.sentence-1)

[6](#void.cons-6)

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

This constructor is trivial
if is_trivially_copy_constructible_v<E> is true[.](#void.cons-6.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor__)

`constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
`

[7](#void.cons-7)

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

*Constraints*: is_move_constructible_v<E> is true[.](#void.cons-7.sentence-1)

[8](#void.cons-8)

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

*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with std​::​move(rhs.error())[.](#void.cons-8.sentence-1)

[9](#void.cons-9)

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

*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#void.cons-9.sentence-1)

[10](#void.cons-10)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-10.sentence-1)

[11](#void.cons-11)

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

*Remarks*: This constructor is trivial
if is_trivially_move_constructible_v<E> is true[.](#void.cons-11.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor___)

`template<class U, class G>
  constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs);
template<class U, class G>
  constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>&& rhs);
`

[12](#void.cons-12)

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

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

[13](#void.cons-13)

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

*Constraints*: 

- [(13.1)](#void.cons-13.1)

is_void_v<U> is true; and

- [(13.2)](#void.cons-13.2)

is_constructible_v<E, GF> is true; and

- [(13.3)](#void.cons-13.3)

is_constructible_v<unexpected<E>, expected<U, G>&> is false; and

- [(13.4)](#void.cons-13.4)

is_constructible_v<unexpected<E>, expected<U, G>> is false; and

- [(13.5)](#void.cons-13.5)

is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and

- [(13.6)](#void.cons-13.6)

is_constructible_v<unexpected<E>, const expected<U, G>> is false[.](#void.cons-13.sentence-1)

[14](#void.cons-14)

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

*Effects*: If rhs.has_value() is false,
direct-non-list-initializes *unex* with std​::​forward<GF>(rhs.error())[.](#void.cons-14.sentence-1)

[15](#void.cons-15)

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

*Postconditions*: rhs.has_value() is unchanged;rhs.has_value() == this->has_value() is true[.](#void.cons-15.sentence-1)

[16](#void.cons-16)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-16.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor____)

`template<class G>
  constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e);
template<class G>
  constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>&& e);
`

[17](#void.cons-17)

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

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

[18](#void.cons-18)

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

*Constraints*: is_constructible_v<E, GF> is true[.](#void.cons-18.sentence-1)

[19](#void.cons-19)

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

*Effects*: Direct-non-list-initializes *unex* with std​::​forward<GF>(e.error())[.](#void.cons-19.sentence-1)

[20](#void.cons-20)

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

*Postconditions*: has_value() is false[.](#void.cons-20.sentence-1)

[21](#void.cons-21)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-21.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor_____)

`constexpr explicit expected(in_place_t) noexcept;
`

[22](#void.cons-22)

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

*Postconditions*: has_value() is true[.](#void.cons-22.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor______)

`template<class... Args>
  constexpr explicit expected(unexpect_t, Args&&... args);
`

[23](#void.cons-23)

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

*Constraints*: is_constructible_v<E, Args...> is true[.](#void.cons-23.sentence-1)

[24](#void.cons-24)

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

*Effects*: Direct-non-list-initializes *unex* with std​::​forward<Args>(args)...[.](#void.cons-24.sentence-1)

[25](#void.cons-25)

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

*Postconditions*: has_value() is false[.](#void.cons-25.sentence-1)

[26](#void.cons-26)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-26.sentence-1)

[ð](#lib:expected%3cvoid%3e,constructor_______)

`template<class U, class... Args>
  constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&... args);
`

[27](#void.cons-27)

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

*Constraints*: is_constructible_v<E, initializer_list<U>&, Args...> is true[.](#void.cons-27.sentence-1)

[28](#void.cons-28)

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

*Effects*: Direct-non-list-initializes *unex* with il, std​::​forward<Args>(args)...[.](#void.cons-28.sentence-1)

[29](#void.cons-29)

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

*Postconditions*: has_value() is false[.](#void.cons-29.sentence-1)

[30](#void.cons-30)

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

*Throws*: Any exception thrown by the initialization of *unex*[.](#void.cons-30.sentence-1)

#### [22.8.7.3](#void.dtor) Destructor [[expected.void.dtor]](expected.void.dtor)

[ð](#lib:expected%3cvoid%3e,destructor)

`constexpr ~expected();
`

[1](#void.dtor-1)

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

*Effects*: If has_value() is false, destroys *unex*[.](#void.dtor-1.sentence-1)

[2](#void.dtor-2)

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

*Remarks*: If is_trivially_destructible_v<E> is true,
then this destructor is a trivial destructor[.](#void.dtor-2.sentence-1)

#### [22.8.7.4](#void.assign) Assignment [[expected.void.assign]](expected.void.assign)

[ð](#lib:operator=,expected%3cvoid%3e)

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

[1](#void.assign-1)

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

*Effects*: 

- [(1.1)](#void.assign-1.1)

  If this->has_value() && rhs.has_value() is true, no effects[.](#void.assign-1.1.sentence-1)

- [(1.2)](#void.assign-1.2)

  Otherwise, if this->has_value() is true,
equivalent to: construct_at(addressof(*unex*), rhs.*unex*); *has_val* = false;

- [(1.3)](#void.assign-1.3)

  Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#void.assign-1.3.sentence-1)

- [(1.4)](#void.assign-1.4)

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

[2](#void.assign-2)

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

*Returns*: *this[.](#void.assign-2.sentence-1)

[3](#void.assign-3)

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

*Remarks*: This operator is defined as deleted unlessis_copy_assignable_v<E> is true andis_copy_constructible_v<E> is true[.](#void.assign-3.sentence-1)

[ð](#lib:operator=,expected%3cvoid%3e_)

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

[4](#void.assign-4)

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

*Constraints*: is_move_constructible_v<E> is true andis_move_assignable_v<E> is true[.](#void.assign-4.sentence-1)

[5](#void.assign-5)

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

*Effects*: 

- [(5.1)](#void.assign-5.1)

  If this->has_value() && rhs.has_value() is true, no effects[.](#void.assign-5.1.sentence-1)

- [(5.2)](#void.assign-5.2)

  Otherwise, if this->has_value() is true, equivalent to:construct_at(addressof(*unex*), std::move(rhs.*unex*));*has_val* = false;

- [(5.3)](#void.assign-5.3)

  Otherwise, if rhs.has_value() is true,
destroys *unex* and sets *has_val* to true[.](#void.assign-5.3.sentence-1)

- [(5.4)](#void.assign-5.4)

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

[6](#void.assign-6)

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

*Returns*: *this[.](#void.assign-6.sentence-1)

[7](#void.assign-7)

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

*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>[.](#void.assign-7.sentence-1)

[ð](#lib:operator=,expected%3cvoid%3e__)

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

[8](#void.assign-8)

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

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

[9](#void.assign-9)

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

*Constraints*: is_constructible_v<E, GF> is true andis_assignable_v<E&, GF> is true[.](#void.assign-9.sentence-1)

[10](#void.assign-10)

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

*Effects*: 

- [(10.1)](#void.assign-10.1)

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

- [(10.2)](#void.assign-10.2)

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

[11](#void.assign-11)

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

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

[ð](#lib:emplace,expected%3cvoid%3e)

`constexpr void emplace() noexcept;
`

[12](#void.assign-12)

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

*Effects*: If has_value() is false,
destroys *unex* and sets *has_val* to true[.](#void.assign-12.sentence-1)

#### [22.8.7.5](#void.swap) Swap [[expected.void.swap]](expected.void.swap)

[ð](#lib:swap,expected%3cvoid%3e)

`constexpr void swap(expected& rhs) noexcept(see below);
`

[1](#void.swap-1)

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

*Constraints*: is_swappable_v<E> is true andis_move_constructible_v<E> is true[.](#void.swap-1.sentence-1)

[2](#void.swap-2)

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

*Effects*: See Table [73](#tab:expected.void.swap "Table 73: swap(expected&amp;) effects")[.](#void.swap-2.sentence-1)

Table [73](#tab:expected.void.swap) — swap(expected&) effects [[tab:expected.void.swap]](./tab:expected.void.swap)  

| [ð](#tab:expected.void.swap-row-1) | **this->has_value()** | **!this->has_value()** |
| --- | --- | --- |
| [ð](#tab:expected.void.swap-row-2)<br>**rhs.has_value()** | no effects | calls rhs.swap(*this) |
| [ð](#tab:expected.void.swap-row-3)<br>**!rhs.has_value()** | *see below* | equivalent to: using std​::​swap; swap(*unex*, rhs.*unex*); |

For the case where rhs.has_value() is false andthis->has_value() is true, equivalent to:construct_at(addressof(*unex*), std::move(rhs.*unex*));
destroy_at(addressof(rhs.*unex*));*has_val* = false;
rhs.*has_val* = true;

[3](#void.swap-3)

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

*Throws*: Any exception thrown by the expressions in the *Effects*[.](#void.swap-3.sentence-1)

[4](#void.swap-4)

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

*Remarks*: The exception specification is equivalent tois_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>[.](#void.swap-4.sentence-1)

[ð](#lib:swap,expected%3cvoid%3e_)

`friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
`

[5](#void.swap-5)

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

*Effects*: Equivalent to x.swap(y)[.](#void.swap-5.sentence-1)

#### [22.8.7.6](#void.obs) Observers [[expected.void.obs]](expected.void.obs)

[ð](#lib:operator_bool,expected%3cvoid%3e)

`constexpr explicit operator bool() const noexcept;
constexpr bool has_value() const noexcept;
`

[1](#void.obs-1)

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

*Returns*: *has_val*[.](#void.obs-1.sentence-1)

[ð](#lib:operator*,expected%3cvoid%3e)

`constexpr void operator*() const noexcept;
`

[2](#void.obs-2)

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

*Hardened preconditions*: has_value() is true[.](#void.obs-2.sentence-1)

[ð](#lib:value,expected%3cvoid%3e)

`constexpr void value() const &;
`

[3](#void.obs-3)

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

*Mandates*: is_copy_constructible_v<E> is true[.](#void.obs-3.sentence-1)

[4](#void.obs-4)

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

*Throws*: bad_expected_access(error()) if has_value() is false[.](#void.obs-4.sentence-1)

[ð](#lib:value,expected%3cvoid%3e_)

`constexpr void value() &&;
`

[5](#void.obs-5)

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

*Mandates*: is_copy_constructible_v<E> is true andis_move_constructible_v<E> is true[.](#void.obs-5.sentence-1)

[6](#void.obs-6)

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

*Throws*: bad_expected_access(std​::​move(error())) if has_value() is false[.](#void.obs-6.sentence-1)

[ð](#lib:error,expected%3cvoid%3e)

`constexpr const E& error() const & noexcept;
constexpr E& error() & noexcept;
`

[7](#void.obs-7)

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

*Hardened preconditions*: has_value() is false[.](#void.obs-7.sentence-1)

[8](#void.obs-8)

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

*Returns*: *unex*[.](#void.obs-8.sentence-1)

[ð](#lib:error,expected%3cvoid%3e_)

`constexpr E&& error() && noexcept;
constexpr const E&& error() const && noexcept;
`

[9](#void.obs-9)

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

*Hardened preconditions*: has_value() is false[.](#void.obs-9.sentence-1)

[10](#void.obs-10)

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

*Returns*: std​::​move(*unex*)[.](#void.obs-10.sentence-1)

[ð](#lib:error_or,expected%3cvoid%3e)

`template<class G = E> constexpr E error_or(G&& e) const &;
`

[11](#void.obs-11)

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

*Mandates*: is_copy_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#void.obs-11.sentence-1)

[12](#void.obs-12)

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

*Returns*: std​::​forward<G>(e) if has_value() is true,error() otherwise[.](#void.obs-12.sentence-1)

[ð](#lib:error_or,expected%3cvoid%3e_)

`template<class G = E> constexpr E error_or(G&& e) &&;
`

[13](#void.obs-13)

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

*Mandates*: is_move_constructible_v<E> is true andis_convertible_v<G, E> is true[.](#void.obs-13.sentence-1)

[14](#void.obs-14)

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

*Returns*: std​::​forward<G>(e) if has_value() is true,std​::​move(error()) otherwise[.](#void.obs-14.sentence-1)

#### [22.8.7.7](#void.monadic) Monadic operations [[expected.void.monadic]](expected.void.monadic)

[ð](#lib:and_then,expected%3cvoid%3e)

`template<class F> constexpr auto and_then(F&& f) &;
template<class F> constexpr auto and_then(F&& f) const &;
`

[1](#void.monadic-1)

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

Let U be remove_cvref_t<invoke_result_t<F>>[.](#void.monadic-1.sentence-1)

[2](#void.monadic-2)

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

*Constraints*: is_constructible_v<E, decltype(error())>> is true[.](#void.monadic-2.sentence-1)

[3](#void.monadic-3)

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

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#void.monadic-3.sentence-1)

[4](#void.monadic-4)

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

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, error());

[ð](#lib:and_then,expected%3cvoid%3e_)

`template<class F> constexpr auto and_then(F&& f) &&;
template<class F> constexpr auto and_then(F&& f) const &&;
`

[5](#void.monadic-5)

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

Let U be remove_cvref_t<invoke_result_t<F>>[.](#void.monadic-5.sentence-1)

[6](#void.monadic-6)

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

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#void.monadic-6.sentence-1)

[7](#void.monadic-7)

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

*Mandates*: U is a specialization of expected andis_same_v<U​::​error_type, E> is true[.](#void.monadic-7.sentence-1)

[8](#void.monadic-8)

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

*Effects*: Equivalent to:if (has_value())return invoke(std::forward<F>(f));elsereturn U(unexpect, std::move(error()));

[ð](#lib:or_else,expected%3cvoid%3e)

`template<class F> constexpr auto or_else(F&& f) &;
template<class F> constexpr auto or_else(F&& f) const &;
`

[9](#void.monadic-9)

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

Let G be remove_cvref_t<invoke_result_t<F, decltype(error())>>[.](#void.monadic-9.sentence-1)

[10](#void.monadic-10)

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

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#void.monadic-10.sentence-1)

[11](#void.monadic-11)

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

*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), error());

[ð](#lib:or_else,expected%3cvoid%3e_)

`template<class F> constexpr auto or_else(F&& f) &&;
template<class F> constexpr auto or_else(F&& f) const &&;
`

[12](#void.monadic-12)

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

Let G beremove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#void.monadic-12.sentence-1)

[13](#void.monadic-13)

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

*Mandates*: G is a specialization of expected andis_same_v<G​::​value_type, T> is true[.](#void.monadic-13.sentence-1)

[14](#void.monadic-14)

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

*Effects*: Equivalent to:if (has_value())return G();elsereturn invoke(std::forward<F>(f), std::move(error()));

[ð](#lib:transform,expected%3cvoid%3e)

`template<class F> constexpr auto transform(F&& f) &;
template<class F> constexpr auto transform(F&& f) const &;
`

[15](#void.monadic-15)

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

Let U be remove_cv_t<invoke_result_t<F>>[.](#void.monadic-15.sentence-1)

[16](#void.monadic-16)

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

*Constraints*: is_constructible_v<E, decltype(error())> is true[.](#void.monadic-16.sentence-1)

[17](#void.monadic-17)

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

*Mandates*: U is a valid value type for expected[.](#void.monadic-17.sentence-1)

If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#void.monadic-17.sentence-2)

[18](#void.monadic-18)

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

*Effects*: 

- [(18.1)](#void.monadic-18.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, error())[.](#void.monadic-18.1.sentence-1)

- [(18.2)](#void.monadic-18.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f))[.](#void.monadic-18.2.sentence-1)

- [(18.3)](#void.monadic-18.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returnsexpected<U, E>()[.](#void.monadic-18.3.sentence-1)

[ð](#lib:transform,expected%3cvoid%3e_)

`template<class F> constexpr auto transform(F&& f) &&;
template<class F> constexpr auto transform(F&& f) const &&;
`

[19](#void.monadic-19)

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

Let U be remove_cv_t<invoke_result_t<F>>[.](#void.monadic-19.sentence-1)

[20](#void.monadic-20)

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

*Constraints*: is_constructible_v<E, decltype(std​::​move(error()))> is true[.](#void.monadic-20.sentence-1)

[21](#void.monadic-21)

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

*Mandates*: U is a valid value type for expected[.](#void.monadic-21.sentence-1)

If is_void_v<U> isfalse, the declarationU u(invoke(std::forward<F>(f))); is well-formed[.](#void.monadic-21.sentence-2)

[22](#void.monadic-22)

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

*Effects*: 

- [(22.1)](#void.monadic-22.1)

  If has_value() is false, returnsexpected<U, E>(unexpect, std​::​move(error()))[.](#void.monadic-22.1.sentence-1)

- [(22.2)](#void.monadic-22.2)

  Otherwise, if is_void_v<U> is false, returns anexpected<U, E> object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f))[.](#void.monadic-22.2.sentence-1)

- [(22.3)](#void.monadic-22.3)

  Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returnsexpected<U, E>()[.](#void.monadic-22.3.sentence-1)

[ð](#lib:transform_error,expected%3cvoid%3e)

`template<class F> constexpr auto transform_error(F&& f) &;
template<class F> constexpr auto transform_error(F&& f) const &;
`

[23](#void.monadic-23)

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

Let G be remove_cv_t<invoke_result_t<F, decltype(error())>>[.](#void.monadic-23.sentence-1)

[24](#void.monadic-24)

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

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), error())); is well-formed[.](#void.monadic-24.sentence-1)

[25](#void.monadic-25)

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

*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), error())[.](#void.monadic-25.sentence-1)

[ð](#lib:transform_error,expected%3cvoid%3e_)

`template<class F> constexpr auto transform_error(F&& f) &&;
template<class F> constexpr auto transform_error(F&& f) const &&;
`

[26](#void.monadic-26)

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

Let G beremove_cv_t<invoke_result_t<F, decltype(std​::​move(error()))>>[.](#void.monadic-26.sentence-1)

[27](#void.monadic-27)

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

*Mandates*: G is a valid template argument
for unexpected ([[expected.un.general]](#un.general "22.8.3.1 General")) and the declarationG g(invoke(std::forward<F>(f), std::move(error()))); is well-formed[.](#void.monadic-27.sentence-1)

[28](#void.monadic-28)

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

*Returns*: If has_value() is true, expected<T, G>(); otherwise, anexpected<T, G> object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward<F>(f), std​::​move(error()))[.](#void.monadic-28.sentence-1)

#### [22.8.7.8](#void.eq) Equality operators [[expected.void.eq]](expected.void.eq)

[ð](#lib:operator==,expected%3cvoid%3e)

`template<class T2, class E2> requires is_void_v<T2>
  friend constexpr bool operator==(const expected& x, const expected<T2, E2>& y);
`

[1](#void.eq-1)

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

*Constraints*: The expression x.error() == y.error() is well-formed and
its result is convertible to bool[.](#void.eq-1.sentence-1)

[2](#void.eq-2)

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

*Returns*: If x.has_value() does not equal y.has_value(), false;
otherwise x.has_value() || static_cast<bool>(x.error() == y.error())[.](#void.eq-2.sentence-1)

[ð](#lib:operator==,expected%3cvoid%3e_)

`template<class E2>
  friend constexpr bool operator==(const expected& x, const unexpected<E2>& e);
`

[3](#void.eq-3)

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

*Constraints*: The expression x.error() == e.error() is well-formed and
its result is convertible to bool[.](#void.eq-3.sentence-1)

[4](#void.eq-4)

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

*Returns*: !x.has_value() && static_cast<bool>(x.error() == e.error())[.](#void.eq-4.sentence-1)
