22 General utilities library [utilities]

22.8 Expected objects [expected]

22.8.7 Partial specialization of expected for void types [expected.void]


22.8.7.1 General [expected.void.general]

22.8.7.2 Constructors [expected.void.cons]

22.8.7.3 Destructor [expected.void.dtor]

22.8.7.4 Assignment [expected.void.assign]

22.8.7.5 Swap [expected.void.swap]

22.8.7.6 Observers [expected.void.obs]

22.8.7.7 Monadic operations [expected.void.monadic]

22.8.7.8 Equality operators [expected.void.eq]


22.8.7.1 General [expected.void.general]

template<class T, class E> requires is_void_v<T> class expected<T, E> { public: using value_type = T; using error_type = E; using unexpected_type = unexpected<E>; template<class U> using rebind = expected<U, error_type>; / [expected.void.cons], constructors constexpr expected() noexcept; constexpr expected(const expected&); constexpr expected(expected&&) noexcept(see below); template<class U, class G> constexpr explicit(see below) expected(const expected<U, G>&); template<class U, class G> constexpr explicit(see below) expected(expected<U, G>&); template<class G> constexpr explicit(see below) expected(const unexpected<G>&); template<class G> constexpr explicit(see below) expected(unexpected<G>&); constexpr explicit expected(in_place_t) noexcept; template<class. Args> constexpr explicit expected(unexpect_t, Args&&.); template<class U, class. Args> constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&.); / [expected.void.dtor], destructor constexpr ~expected(); / [expected.void.assign], assignment constexpr expected& operator=(const expected&); constexpr expected& operator=(expected&&) noexcept(see below); template<class G> constexpr expected& operator=(const unexpected<G>&); template<class G> constexpr expected& operator=(unexpected<G>&); constexpr void emplace() noexcept; / [expected.void.swap], swap constexpr void swap(expected&) noexcept(see below); friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)); / [expected.void.obs], observers constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept; constexpr void operator*() const noexcept; constexpr void value() const &; / freestanding-deleted constexpr void value() &&; / freestanding-deleted constexpr const E& error() const & noexcept; constexpr E& error() & noexcept; constexpr const E&& error() const && noexcept; constexpr E&& error() && noexcept; template<class G = E> constexpr E error_or(G&&) const &; template<class G = E> constexpr E error_or(G&&) &&; / [expected.void.monadic], monadic operations template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &; template<class F> constexpr auto and_then(F&& f) const &&; template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &; template<class F> constexpr auto or_else(F&& f) const &&; template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &; template<class F> constexpr auto transform(F&& f) const &&; template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &; template<class F> constexpr auto transform_error(F&& f) const &&; / [expected.void.eq], equality operators template<class T2, class E2> requires is_void_v<T2> friend constexpr bool operator=(const expected& x, const expected<T2, E2>& y); template<class E2> friend constexpr bool operator=(const expected&, const unexpected<E2>&); private: bool has_val; / exposition only union { E unex; / exposition only }; };
Any object of type expected<T, E> either represents a value of type T, or contains a value of type E nested within ([intro.object]) it.
Member has_val indicates whether the expected<T, E> object represents a value of type T.
A program that instantiates the definition of the template expected<T, E> with a type for the E parameter that is not a valid template argument for unexpected is ill-formed.
E shall meet the requirements of Cpp17Destructible (Table 35).
constexpr expected() noexcept;
Postconditions: has_value() is true.
constexpr expected(const expected& rhs);
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with rhs.error().
Remarks: This constructor is defined as deleted unless is_copy_constructible_v<E> is true.
This constructor is trivial if is_trivially_copy_constructible_v<E> is true.
constexpr expected(expected&& rhs) noexcept(is_nothrow_move_constructible_v<E>);
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std​::​move(rhs.error().
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Remarks: This constructor is trivial if is_trivially_move_constructible_v<E> is true.
template<class U, class G> constexpr explicit(!is_convertible_v<const G&, E>) expected(const expected<U, G>& rhs); template<class U, class G> constexpr explicit(!is_convertible_v<G, E>) expected(expected<U, G>& rhs);
Let GF be const G& for the first overload and G for the second overload.
Constraints:
  • is_void_v<U> is true; and
  • is_constructible_v<E, GF> is true; and
  • is_constructible_v<unexpected<E>, expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, expected<U, G>> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>&> is false; and
  • is_constructible_v<unexpected<E>, const expected<U, G>> is false.
Effects: If rhs.has_value() is false, direct-non-list-initializes unex with std​::​forward<GF>(rhs.error().
Postconditions: rhs.has_value() is unchanged; rhs.has_value() == this->has_value() is true.
Throws: Any exception thrown by the initialization of unex.
template<class G> constexpr explicit(!is_convertible_v<const G&, E>) expected(const unexpected<G>& e); template<class G> constexpr explicit(!is_convertible_v<G, E>) expected(unexpected<G>& e);
Let GF be const G& for the first overload and G for the second overload.
Effects: Direct-non-list-initializes unex with std​::​forward<GF>(e.error().
Throws: Any exception thrown by the initialization of unex.
constexpr explicit expected(in_place_t) noexcept;
Postconditions: has_value() is true.
template<class. Args> constexpr explicit expected(unexpect_t, Args&&. args);
Effects: Direct-non-list-initializes unex with std​::​forward<Args>(args)..
Throws: Any exception thrown by the initialization of unex.
template<class U, class. Args> constexpr explicit expected(unexpect_t, initializer_list<U> il, Args&&. args);
Effects: Direct-non-list-initializes unex with il, std​::​forward<Args>(args)..
Throws: Any exception thrown by the initialization of unex.
constexpr ~expected();
Remarks: If is_trivially_destructible_v<E> is true, then this destructor is a trivial destructor.
constexpr expected& operator=(const expected& rhs);
Effects:
  • If this->has_value() && rhs.has_value() is true, no effects.
  • Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), rhs.unex); has_val = false;
  • Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
  • Otherwise, equivalent to unex = rhs.error().
Remarks: This operator is defined as deleted unless is_copy_assignable_v<E> is true and is_copy_constructible_v<E> is true.
constexpr expected& operator=(expected&& rhs) noexcept(see below);
Constraints: is_move_constructible_v<E> is true and is_move_assignable_v<E> is true.
Effects:
  • If this->has_value() && rhs.has_value() is true, no effects.
  • Otherwise, if this->has_value() is true, equivalent to: construct_at(addressof(unex), std::move(rhs.unex)); has_val = false;
  • Otherwise, if rhs.has_value() is true, destroys unex and sets has_val to true.
  • Otherwise, equivalent to unex = std​::​move(rhs.error().
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_move_assignable_v<E>.
template<class G> constexpr expected& operator=(const unexpected<G>& e); template<class G> constexpr expected& operator=(unexpected<G>& e);
Let GF be const G& for the first overload and G for the second overload.
Constraints: is_constructible_v<E, GF> is true and is_assignable_v<E&, GF> is true.
Effects:
  • If has_value() is true, equivalent to: construct_at(addressof(unex), std::forward<GF>(e.error(); has_val = false;
  • Otherwise, equivalent to: unex = std​::​forward<GF>(e.error();
Returns: *this.
constexpr void emplace() noexcept;
Effects: If has_value() is false, destroys unex and sets has_val to true.
constexpr void swap(expected& rhs) noexcept(see below);
Constraints: is_swappable_v<E> is true and is_move_constructible_v<E> is true.
Effects: See Table 73.
Table 73swap(expected&) effects [tab:expected.void.swap]
this->has_value()
!this->has_value()
rhs.has_value()
no effects
calls rhs.swap(*this)
!rhs.has_value()
see below
equivalent to: using std​::​swap; swap(unex, rhs.unex);
For the case where rhs.has_value() is false and this->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;
Remarks: The exception specification is equivalent to is_nothrow_move_constructible_v<E> && is_nothrow_swappable_v<E>.
friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y));
Effects: Equivalent to x.swap(y).
constexpr explicit operator bool() const noexcept; constexpr bool has_value() const noexcept;
Returns: has_val.
constexpr void operator*() const noexcept;
Hardened preconditions: has_value() is true.
constexpr void value() const &;
Throws: bad_expected_access(error() if has_value() is false.
constexpr void value() &&;
Mandates: is_copy_constructible_v<E> is true and is_move_constructible_v<E> is true.
Throws: bad_expected_access(std​::​move(error() if has_value() is false.
constexpr const E& error() const & noexcept; constexpr E& error() & noexcept;
Returns: unex.
constexpr E&& error() && noexcept; constexpr const E&& error() const && noexcept;
Returns: std​::​move(unex).
template<class G = E> constexpr E error_or(G&& e) const &;
Mandates: is_copy_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, error() otherwise.
template<class G = E> constexpr E error_or(G&& e) &&;
Mandates: is_move_constructible_v<E> is true and is_convertible_v<G, E> is true.
Returns: std​::​forward<G>(e) if has_value() is true, std​::​move(error() otherwise.
template<class F> constexpr auto and_then(F&& f) &; template<class F> constexpr auto and_then(F&& f) const &;
Mandates: U is a specialization of expected and is_same_v<typename U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value() return invoke(std::forward<F>(f)); else return U(unexpect, error();
template<class F> constexpr auto and_then(F&& f) &&; template<class F> constexpr auto and_then(F&& f) const &&;
Mandates: U is a specialization of expected and is_same_v<typename U​::​error_type, E> is true.
Effects: Equivalent to: if (has_value() return invoke(std::forward<F>(f)); else return U(unexpect, std::move(error();
template<class F> constexpr auto or_else(F&& f) &; template<class F> constexpr auto or_else(F&& f) const &;
Mandates: G is a specialization of expected and is_same_v<typename G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value() return G(); else return invoke(std::forward<F>(f), error();
template<class F> constexpr auto or_else(F&& f) &&; template<class F> constexpr auto or_else(F&& f) const &&;
Let G be remove_cvref_t<invoke_result_t<F, decltype(std​::​move(error()>.
Mandates: G is a specialization of expected and is_same_v<typename G​::​value_type, T> is true.
Effects: Equivalent to: if (has_value() return G(); else return invoke(std::forward<F>(f), std::move(error();
template<class F> constexpr auto transform(F&& f) &; template<class F> constexpr auto transform(F&& f) const &;
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f)); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, error().
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f)).
  • Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returns expected<U, E>().
template<class F> constexpr auto transform(F&& f) &&; template<class F> constexpr auto transform(F&& f) const &&;
Mandates: U is a valid value type for expected.
If is_void_v<U> is false, the declaration U u(invoke(std::forward<F>(f)); is well-formed.
Effects:
  • If has_value() is false, returns expected<U, E>(unexpect, std​::​move(error().
  • Otherwise, if is_void_v<U> is false, returns an expected<U, E> object whose has_val member is true and val member is direct-non-list-initialized with invoke(std​::​forward<F>(f)).
  • Otherwise, evaluates invoke(std​::​forward<F>(f)) and then returns expected<U, E>().
template<class F> constexpr auto transform_error(F&& f) &; template<class F> constexpr auto transform_error(F&& f) const &;
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), error(); is well-formed.
Returns: If has_value() is true, expected<T, G>(); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), error().
template<class F> constexpr auto transform_error(F&& f) &&; template<class F> constexpr auto transform_error(F&& f) const &&;
Let G be remove_cv_t<invoke_result_t<F, decltype(std​::​move(error()>.
Mandates: G is a valid template argument for unexpected ([expected.un.general]) and the declaration G g(invoke(std::forward<F>(f), std::move(error(); is well-formed.
Returns: If has_value() is true, expected<T, G>(); otherwise, an expected<T, G> object whose has_val member is false and unex member is direct-non-list-initialized with invoke(std​::​forward<F>(f), std​::​move(error().

22.8.7.8 Equality operators [expected.void.eq]

template<class T2, class E2> requires is_void_v<T2> friend constexpr bool operator=(const expected& x, const expected<T2, E2>& y);
Constraints: The expression x.error() == y.error() is well-formed and its result is convertible to bool.
Returns: If x.has_value() does not equal y.has_value(), false; otherwise if x.has_value() is true, true; otherwise x.error() == y.error().
template<class E2> friend constexpr bool operator=(const expected& x, const unexpected<E2>& e);
Constraints: The expression x.error() == e.error() is well-formed and its result is convertible to bool.
Returns: If !x.has_value() is true, x.error() == e.error(); otherwise false.

Follow Lee on X/Twitter - Father, Husband, Serial builder creating AI, crypto, games & web tools. We are friends :) AI Will Come To Life!

Check out: eBank.nz (Art Generator) | Netwrck.com (AI Tools) | Text-Generator.io (AI API) | BitBank.nz (Crypto AI) | ReadingTime (Kids Reading) | RewordGame | BigMultiplayerChess | WebFiddle | How.nz | Helix AI Assistant