[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 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 synopsis [[expected.syn]](expected.syn) [🔗](#header:%3cexpected%3e) // mostly freestandingnamespace std {// [[expected.unexpected]](#unexpected "22.8.3 Class template unexpected"), class template unexpectedtemplate class unexpected; // [[expected.bad]](#bad "22.8.4 Class template bad_­expected_­access"), class template bad_expected_accesstemplate class bad_expected_access; // [[expected.bad.void]](#bad.void "22.8.5 Class template specialization bad_­expected_­access"), specialization for voidtemplate<> class bad_expected_access; // 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 expected; // partially freestanding// [[expected.void]](#void "22.8.7 Partial specialization of expected for void types"), partial specialization of expected for void typestemplate requires is_void_v class expected; // 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 {templateclass unexpected {public:// [[expected.un.cons]](#un.cons "22.8.3.2 Constructors"), constructorsconstexpr unexpected(const unexpected&) = default; constexpr unexpected(unexpected&&) = default; templateconstexpr explicit unexpected(Err&&); templateconstexpr explicit unexpected(in_place_t, Args&&...); templateconstexpr explicit unexpected(in_place_t, initializer_list, 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*); templatefriend constexpr bool operator==(const unexpected&, const unexpected&); friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y))); private: E *unex*; // *exposition only*}; template unexpected(E) -> unexpected;} [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 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, unexpected> is false; and - [(1.2)](#un.cons-1.2) is_same_v, in_place_t> is false; and - [(1.3)](#un.cons-1.3) is_constructible_v 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(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 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 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)...[.](#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 constexpr explicit unexpected(in_place_t, initializer_list il, Args&&... args); ` [7](#un.cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7806) *Constraints*: is_constructible_v&, 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)...[.](#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); ` [1](#un.swap-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L7854) *Mandates*: is_swappable_v 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 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 friend constexpr bool operator==(const unexpected& x, const unexpected& 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 {templateclass bad_expected_access : public bad_expected_access {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 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 [[expected.bad.void]](expected.bad.void) namespace std {template<>class bad_expected_access : 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 {templateclass 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; templateusing [rebind](#lib:expected,rebind "22.8.6.1 General [expected.object.general]") = expected; // [[expected.object.cons]](#object.cons "22.8.6.2 Constructors"), constructorsconstexpr expected(); constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); templateconstexpr explicit(*see below*) expected(const expected&); templateconstexpr explicit(*see below*) expected(expected&&); template>constexpr explicit(*see below*) expected(U&& v); templateconstexpr explicit(*see below*) expected(const unexpected&); templateconstexpr explicit(*see below*) expected(unexpected&&); templateconstexpr explicit expected(in_place_t, Args&&...); templateconstexpr explicit expected(in_place_t, initializer_list, Args&&...); templateconstexpr explicit expected(unexpect_t, Args&&...); templateconstexpr explicit expected(unexpect_t, initializer_list, 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> constexpr expected& operator=(U&&); templateconstexpr expected& operator=(const unexpected&); templateconstexpr expected& operator=(unexpected&&); templateconstexpr T& emplace(Args&&...) noexcept; templateconstexpr T& emplace(initializer_list, 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> constexpr T value_or(U&&) const &; template> constexpr T value_or(U&&) &&; template constexpr E error_or(G&&) const &; template constexpr E error_or(G&&) &&; // [[expected.object.monadic]](#object.monadic "22.8.6.7 Monadic operations"), monadic operationstemplate constexpr auto and_then(F&& f) &; template constexpr auto and_then(F&& f) &&; template constexpr auto and_then(F&& f) const &; template constexpr auto and_then(F&& f) const &&; template constexpr auto or_else(F&& f) &; template constexpr auto or_else(F&& f) &&; template constexpr auto or_else(F&& f) const &; template constexpr auto or_else(F&& f) const &&; template constexpr auto transform(F&& f) &; template constexpr auto transform(F&& f) &&; template constexpr auto transform(F&& f) const &; template constexpr auto transform(F&& f) const &&; template constexpr auto transform_error(F&& f) &; template constexpr auto transform_error(F&& f) &&; template constexpr auto transform_error(F&& f) const &; template constexpr auto transform_error(F&& f) const &&; // [[expected.object.eq]](#object.eq "22.8.6.8 Equality operators"), equality operatorstemplate requires (!is_void_v)friend constexpr bool operator==(const expected& x, const expected& y); templatefriend constexpr bool operator==(const expected&, const T2&); templatefriend constexpr bool operator==(const expected&, const unexpected&); 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 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 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 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 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 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 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 is true and - [(9.2)](#object.cons-9.2) is_copy_constructible_v 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 is true and - [(10.2)](#object.cons-10.2) is_trivially_copy_constructible_v 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 is true and - [(11.2)](#object.cons-11.2) is_move_constructible_v 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 && is_nothrow_move_constructible_v[.](#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 is true and - [(16.2)](#object.cons-16.2) is_trivially_move_constructible_v is true[.](#object.cons-16.sentence-1) [🔗](#lib:expected,constructor___) `template constexpr explicit(see below) expected(const expected& rhs); template constexpr explicit(see below) expected(expected&& 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 is true; and - [(18.2)](#object.cons-18.2) is_constructible_v is true; and - [(18.3)](#object.cons-18.3) if T is not cv bool,*converts-from-any-cvref*> is false; and - [(18.4)](#object.cons-18.4) is_constructible_v, expected&> is false; and - [(18.5)](#object.cons-18.5) is_constructible_v, expected> is false; and - [(18.6)](#object.cons-18.6) is_constructible_v, const expected&> is false; and - [(18.7)](#object.cons-18.7) is_constructible_v, const expected> 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(*rhs)[.](#object.cons-19.sentence-1) Otherwise, direct-non-list-initializes *unex* with std​::​forward(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 || !is_convertible_v[.](#object.cons-22.sentence-1) [🔗](#lib:expected,constructor____) `template> constexpr explicit(!is_convertible_v) 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, in_place_t> is false; and - [(23.2)](#object.cons-23.2) is_same_v, expected> is false; and - [(23.3)](#object.cons-23.3) is_same_v, unexpect_t> is false; and - [(23.4)](#object.cons-23.4) remove_cvref_t is not a specialization of unexpected; and - [(23.5)](#object.cons-23.5) is_constructible_v is true; and - [(23.6)](#object.cons-23.6) if T is cv bool,remove_cvref_t 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(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 constexpr explicit(!is_convertible_v) expected(const unexpected& e); template constexpr explicit(!is_convertible_v) expected(unexpected&& 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 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(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 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 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)...[.](#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 constexpr explicit expected(in_place_t, initializer_list il, Args&&... args); ` [36](#object.cons-36) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8432) *Constraints*: is_constructible_v&, 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)...[.](#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 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 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)...[.](#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 constexpr explicit expected(unexpect_t, initializer_list il, Args&&... args); ` [44](#object.cons-44) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8482) *Constraints*: is_constructible_v&, 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)...[.](#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 is true, andis_trivially_destructible_v 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:templateconstexpr void *reinit-expected*(T& newval, U& oldval, Args&&... args) { // *exposition only*if constexpr (is_nothrow_constructible_v) { destroy_at(addressof(oldval)); construct_at(addressof(newval), std::forward(args)...); } else if constexpr (is_nothrow_move_constructible_v) { T tmp(std::forward(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)...); } 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 is true and - [(4.2)](#object.assign-4.2) is_copy_constructible_v is true and - [(4.3)](#object.assign-4.3) is_copy_assignable_v is true and - [(4.4)](#object.assign-4.4) is_copy_constructible_v is true and - [(4.5)](#object.assign-4.5) is_nothrow_move_constructible_v || is_nothrow_move_constructible_v 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 is true and - [(5.2)](#object.assign-5.2) is_move_assignable_v is true and - [(5.3)](#object.assign-5.3) is_move_constructible_v is true and - [(5.4)](#object.assign-5.4) is_move_assignable_v is true and - [(5.5)](#object.assign-5.5) is_nothrow_move_constructible_v || is_nothrow_move_constructible_v 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 && is_nothrow_move_constructible_v && is_nothrow_move_assignable_v && is_nothrow_move_constructible_v [🔗](#lib:operator=,expected__) `template> 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> is false; and - [(9.2)](#object.assign-9.2) remove_cvref_t is not a specialization of unexpected; and - [(9.3)](#object.assign-9.3) is_constructible_v is true; and - [(9.4)](#object.assign-9.4) is_assignable_v is true; and - [(9.5)](#object.assign-9.5) is_nothrow_constructible_v || is_nothrow_move_constructible_v || is_nothrow_move_constructible_v 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(v); - [(10.2)](#object.assign-10.2) Otherwise, equivalent to:*reinit-expected*(*val*, *unex*, std::forward(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 constexpr expected& operator=(const unexpected& e); template constexpr expected& operator=(unexpected&& 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 is true; and - [(13.2)](#object.assign-13.2) is_assignable_v is true; and - [(13.3)](#object.assign-13.3) is_nothrow_constructible_v || is_nothrow_move_constructible_v || is_nothrow_move_constructible_v 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(e.error()));*has_val* = false; - [(14.2)](#object.assign-14.2) Otherwise, equivalent to:*unex* = std​::​forward(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 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 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)...); [🔗](#lib:emplace,expected_) `template constexpr T& emplace(initializer_list il, Args&&... args) noexcept; ` [18](#object.assign-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L8773) *Constraints*: is_nothrow_constructible_v&, 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)...); #### [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 is true and - [(1.2)](#object.swap-1.2) is_swappable_v is true and - [(1.3)](#object.swap-1.3) is_move_constructible_v && is_move_constructible_v is true, and - [(1.4)](#object.swap-1.4) is_nothrow_move_constructible_v || is_nothrow_move_constructible_v 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&) 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)
**rhs.has_value()** | equivalent to: using std​::​swap; swap(*val*, rhs.*val*); | calls rhs.swap(*this) | | [🔗](#tab:expected.object.swap-row-3)
**!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 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 && is_nothrow_swappable_v && is_nothrow_move_constructible_v && is_nothrow_swappable_v [🔗](#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 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 is true andis_constructible_v 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> 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 is true andis_convertible_v 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(std​::​forward(v))[.](#object.obs-19.sentence-1) [🔗](#lib:value_or,expected_) `template> 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 is true andis_convertible_v 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(std​::​forward(v))[.](#object.obs-21.sentence-1) [🔗](#lib:error_or,expected) `template 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 is true andis_convertible_v 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(e) if has_value() is true,error() otherwise[.](#object.obs-23.sentence-1) [🔗](#lib:error_or,expected_) `template 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 is true andis_convertible_v 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(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 constexpr auto and_then(F&& f) &; template 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>[.](#object.monadic-1.sentence-1) [2](#object.monadic-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9100) *Constraints*: is_constructible_v 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 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), *val*);elsereturn U(unexpect, error()); [🔗](#lib:and_then,expected_) `template constexpr auto and_then(F&& f) &&; template 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>[.](#object.monadic-5.sentence-1) [6](#object.monadic-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9131) *Constraints*: is_constructible_v 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 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), std::move(*val*));elsereturn U(unexpect, std::move(error())); [🔗](#lib:or_else,expected) `template constexpr auto or_else(F&& f) &; template 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>[.](#object.monadic-9.sentence-1) [10](#object.monadic-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9161) *Constraints*: is_constructible_v 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 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), error()); [🔗](#lib:or_else,expected_) `template constexpr auto or_else(F&& f) &&; template 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>[.](#object.monadic-13.sentence-1) [14](#object.monadic-14) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9192) *Constraints*: is_constructible_v 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 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), std::move(error())); [🔗](#lib:transform,expected) `template constexpr auto transform(F&& f) &; template 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>[.](#object.monadic-17.sentence-1) [18](#object.monadic-18) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9223) *Constraints*: is_constructible_v 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 is false, the declarationU u(invoke(std::forward(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(unexpect, error())[.](#object.monadic-20.1.sentence-1) - [(20.2)](#object.monadic-20.2) Otherwise, if is_void_v is false, returns anexpected object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std​::​forward(f), *val*)[.](#object.monadic-20.2.sentence-1) - [(20.3)](#object.monadic-20.3) Otherwise, evaluates invoke(std​::​forward(f), *val*) and then returns expected()[.](#object.monadic-20.3.sentence-1) [🔗](#lib:transform,expected_) `template constexpr auto transform(F&& f) &&; template 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>[.](#object.monadic-21.sentence-1) [22](#object.monadic-22) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9265) *Constraints*: is_constructible_v 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 isfalse, the declarationU u(invoke(std::forward(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(unexpect, std​::​move(error()))[.](#object.monadic-24.1.sentence-1) - [(24.2)](#object.monadic-24.2) Otherwise, if is_void_v is false, returns anexpected object whose *has_val* member is true and *val* member is direct-non-list-initialized withinvoke(std​::​forward(f), std​::​move(*val*))[.](#object.monadic-24.2.sentence-1) - [(24.3)](#object.monadic-24.3) Otherwise, evaluates invoke(std​::​forward(f), std​::​move(*val*)) and then returns expected()[.](#object.monadic-24.3.sentence-1) [🔗](#lib:transform_error,expected) `template constexpr auto transform_error(F&& f) &; template 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>[.](#object.monadic-25.sentence-1) [26](#object.monadic-26) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9305) *Constraints*: is_constructible_v 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), 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(in_place, *val*); otherwise, an expected object whose *has_val* member is false and *unex* member is direct-non-list-initialized with invoke(std​::​forward(f), error())[.](#object.monadic-28.sentence-1) [🔗](#lib:transform_error,expected_) `template constexpr auto transform_error(F&& f) &&; template 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>[.](#object.monadic-29.sentence-1) [30](#object.monadic-30) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9337) *Constraints*: is_constructible_v 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), 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(in_place, std​::​move(*val*)); otherwise, anexpected object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward(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 requires (!is_void_v) friend constexpr bool operator==(const expected& x, const expected& 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 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(*x == v)[.](#object.eq-4.sentence-1) [🔗](#lib:operator==,expected__) `template friend constexpr bool operator==(const expected& x, const unexpected& 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(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 requires is_void_vclass expected {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; templateusing [rebind](#lib:expected%3cvoid%3e,rebind "22.8.7.1 General [expected.void.general]") = expected; // [[expected.void.cons]](#void.cons "22.8.7.2 Constructors"), constructorsconstexpr expected() noexcept; constexpr expected(const expected&); constexpr expected(expected&&) noexcept(*see below*); templateconstexpr explicit(*see below*) expected(const expected&); templateconstexpr explicit(*see below*) expected(expected&&); templateconstexpr explicit(*see below*) expected(const unexpected&); templateconstexpr explicit(*see below*) expected(unexpected&&); constexpr explicit expected(in_place_t) noexcept; templateconstexpr explicit expected(unexpect_t, Args&&...); templateconstexpr explicit expected(unexpect_t, initializer_list, 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*); templateconstexpr expected& operator=(const unexpected&); templateconstexpr expected& operator=(unexpected&&); 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 constexpr E error_or(G&&) const &; template constexpr E error_or(G&&) &&; // [[expected.void.monadic]](#void.monadic "22.8.7.7 Monadic operations"), monadic operationstemplate constexpr auto and_then(F&& f) &; template constexpr auto and_then(F&& f) &&; template constexpr auto and_then(F&& f) const &; template constexpr auto and_then(F&& f) const &&; template constexpr auto or_else(F&& f) &; template constexpr auto or_else(F&& f) &&; template constexpr auto or_else(F&& f) const &; template constexpr auto or_else(F&& f) const &&; template constexpr auto transform(F&& f) &; template constexpr auto transform(F&& f) &&; template constexpr auto transform(F&& f) const &; template constexpr auto transform(F&& f) const &&; template constexpr auto transform_error(F&& f) &; template constexpr auto transform_error(F&& f) &&; template constexpr auto transform_error(F&& f) const &; template constexpr auto transform_error(F&& f) const &&; // [[expected.void.eq]](#void.eq "22.8.7.8 Equality operators"), equality operatorstemplate requires is_void_vfriend constexpr bool operator==(const expected& x, const expected& y); templatefriend constexpr bool operator==(const expected&, const unexpected&); 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 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 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 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 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 is true[.](#void.cons-6.sentence-1) [🔗](#lib:expected%3cvoid%3e,constructor__) `constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v); ` [7](#void.cons-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9579) *Constraints*: is_move_constructible_v 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 is true[.](#void.cons-11.sentence-1) [🔗](#lib:expected%3cvoid%3e,constructor___) `template constexpr explicit(!is_convertible_v) expected(const expected& rhs); template constexpr explicit(!is_convertible_v) expected(expected&& 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 is true; and - [(13.2)](#void.cons-13.2) is_constructible_v is true; and - [(13.3)](#void.cons-13.3) is_constructible_v, expected&> is false; and - [(13.4)](#void.cons-13.4) is_constructible_v, expected> is false; and - [(13.5)](#void.cons-13.5) is_constructible_v, const expected&> is false; and - [(13.6)](#void.cons-13.6) is_constructible_v, const expected> 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(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 constexpr explicit(!is_convertible_v) expected(const unexpected& e); template constexpr explicit(!is_convertible_v) expected(unexpected&& 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 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(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 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 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)...[.](#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 constexpr explicit expected(unexpect_t, initializer_list il, Args&&... args); ` [27](#void.cons-27) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L9727) *Constraints*: is_constructible_v&, 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)...[.](#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 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 is true andis_copy_constructible_v 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 is true andis_move_assignable_v 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 && is_nothrow_move_assignable_v[.](#void.assign-7.sentence-1) [🔗](#lib:operator=,expected%3cvoid%3e__) `template constexpr expected& operator=(const unexpected& e); template constexpr expected& operator=(unexpected&& 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 is true andis_assignable_v 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(e.error()));*has_val* = false; - [(10.2)](#void.assign-10.2) Otherwise, equivalent to:*unex* = std​::​forward(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 is true andis_move_constructible_v 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&) 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)
**rhs.has_value()** | no effects | calls rhs.swap(*this) | | [🔗](#tab:expected.void.swap-row-3)
**!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 && is_nothrow_swappable_v[.](#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 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 is true andis_move_constructible_v 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 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 is true andis_convertible_v 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(e) if has_value() is true,error() otherwise[.](#void.obs-12.sentence-1) [🔗](#lib:error_or,expected%3cvoid%3e_) `template 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 is true andis_convertible_v 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(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 constexpr auto and_then(F&& f) &; template 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>[.](#void.monadic-1.sentence-1) [2](#void.monadic-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10080) *Constraints*: is_constructible_v> 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 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));elsereturn U(unexpect, error()); [🔗](#lib:and_then,expected%3cvoid%3e_) `template constexpr auto and_then(F&& f) &&; template 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>[.](#void.monadic-5.sentence-1) [6](#void.monadic-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10110) *Constraints*: is_constructible_v 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 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));elsereturn U(unexpect, std::move(error())); [🔗](#lib:or_else,expected%3cvoid%3e) `template constexpr auto or_else(F&& f) &; template 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>[.](#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 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), error()); [🔗](#lib:or_else,expected%3cvoid%3e_) `template constexpr auto or_else(F&& f) &&; template 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>[.](#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 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), std::move(error())); [🔗](#lib:transform,expected%3cvoid%3e) `template constexpr auto transform(F&& f) &; template 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>[.](#void.monadic-15.sentence-1) [16](#void.monadic-16) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10193) *Constraints*: is_constructible_v 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 isfalse, the declarationU u(invoke(std::forward(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(unexpect, error())[.](#void.monadic-18.1.sentence-1) - [(18.2)](#void.monadic-18.2) Otherwise, if is_void_v is false, returns anexpected object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward(f))[.](#void.monadic-18.2.sentence-1) - [(18.3)](#void.monadic-18.3) Otherwise, evaluates invoke(std​::​forward(f)) and then returnsexpected()[.](#void.monadic-18.3.sentence-1) [🔗](#lib:transform,expected%3cvoid%3e_) `template constexpr auto transform(F&& f) &&; template 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>[.](#void.monadic-19.sentence-1) [20](#void.monadic-20) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/utilities.tex#L10233) *Constraints*: is_constructible_v 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 isfalse, the declarationU u(invoke(std::forward(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(unexpect, std​::​move(error()))[.](#void.monadic-22.1.sentence-1) - [(22.2)](#void.monadic-22.2) Otherwise, if is_void_v is false, returns anexpected object whose *has_val* member is true and*val* member is direct-non-list-initialized withinvoke(std​::​forward(f))[.](#void.monadic-22.2.sentence-1) - [(22.3)](#void.monadic-22.3) Otherwise, evaluates invoke(std​::​forward(f)) and then returnsexpected()[.](#void.monadic-22.3.sentence-1) [🔗](#lib:transform_error,expected%3cvoid%3e) `template constexpr auto transform_error(F&& f) &; template 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>[.](#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), 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(); otherwise, anexpected object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward(f), error())[.](#void.monadic-25.sentence-1) [🔗](#lib:transform_error,expected%3cvoid%3e_) `template constexpr auto transform_error(F&& f) &&; template 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>[.](#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), 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(); otherwise, anexpected object whose *has_val* member is false and *unex* member is direct-non-list-initialized withinvoke(std​::​forward(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 requires is_void_v friend constexpr bool operator==(const expected& x, const expected& 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(x.error() == y.error())[.](#void.eq-2.sentence-1) [🔗](#lib:operator==,expected%3cvoid%3e_) `template friend constexpr bool operator==(const expected& x, const unexpected& 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(x.error() == e.error())[.](#void.eq-4.sentence-1)