Standard library header <expected> (C++23)

From cppreference.com
< cpp‎ | header
 
 
Standard library headers
General utilities
<any> (C++17)
<bitset>
<bit> (C++20)
<charconv> (C++17)
<expected> (C++23)
<format> (C++20)
<functional>
<optional> (C++17)
<tuple> (C++11)
<typeindex> (C++11)
<utility>
<variant> (C++17)
Containers
<array> (C++11)
<deque>
<flat_map> (C++23)
<flat_set> (C++23)
<forward_list> (C++11)
<inplace_vector> (C++26)   
<list>
<map>
<mdspan> (C++23)
<queue>
<set>
<span> (C++20)
<stack>
<unordered_map> (C++11)
<unordered_set> (C++11)
<vector>
Iterators
<iterator>
Ranges
<generator> (C++23)
<ranges> (C++20)
 

This header is part of the general utility library.

Classes

(C++23)
a wrapper that contains either an expected or error value
(class template)
represented as an unexpected value
(class template)
exception indicating checked access to an expected that contains an unexpected value
(class template)
in-place construction tag for unexpected value in expected
(tag)

Synopsis

namespace std {
  // class template unexpected
  template<class E> class unexpected;
 
  // class template bad_expected_access
  template<class E> class bad_expected_access;
 
  // specialization of bad_expected_access for void
  template<> class bad_expected_access<void>;
 
  // in-place construction of unexpected values
  struct unexpect_t {
    explicit unexpect_t() = default;
  };
  inline constexpr unexpect_t unexpect{};
 
  // class template expected
  template<class T, class E> class expected;
 
  // partial specialization of expected for void types
  template<class T, class E> requires is_void_v<T> class expected<T, E>;
}

Class template std::unexpected

namespace std {
  template<class E>
  class unexpected {
  public:
    // constructors
    constexpr unexpected(const unexpected&) = default;
    constexpr unexpected(unexpected&&) = default;
    template<class... Args>
      constexpr explicit unexpected(in_place_t, Args&&...);
    template<class U, class... Args>
      constexpr explicit unexpected(in_place_t, initializer_list<U>, Args&&...);
    template<class Err = E>
      constexpr explicit unexpected(Err&&);
 
    // assignment
    constexpr unexpected& operator=(const unexpected&) = default;
    constexpr unexpected& operator=(unexpected&&) = default;
 
    // observer
    constexpr const E& error() const& noexcept;
    constexpr E& error() & noexcept;
    constexpr const E&& error() const&& noexcept;
    constexpr E&& error() && noexcept;
 
    // swap
    constexpr void swap(unexpected& other) noexcept(/* see description */);
 
    friend constexpr void swap(unexpected& x, unexpected& y) noexcept(noexcept(x.swap(y)));
 
    // equality operator
    template<class E2>
      friend constexpr bool operator==(const unexpected&, const unexpected<E2>&);
 
  private:
    E unex;    // exposition only
  };
 
  template<class E> 
    unexpected(E) -> unexpected<E>;
}

Class template std::bad_expected_access

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

Class template specialization std::bad_expected_access<void>

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

Class template std::expected

namespace std {
  template<class T, class E>
  class expected {
  public:
    using value_type = T;
    using error_type = E;
    using unexpected_type = unexpected<E>;
 
    template<class U>
    using rebind = expected<U, error_type>;
 
    // constructors
    constexpr expected();
    constexpr explicit(/* see description */) 
      expected(const expected&);
    constexpr explicit(/* see description */) 
      expected(expected&&) noexcept(/* see description */);
    template<class U, class G>
      constexpr explicit(/* see description */) expected(const expected<U, G>&);
    template<class U, class G>
      constexpr explicit(/* see description */) expected(expected<U, G>&&);
 
    template<class U = T>
      constexpr explicit(/* see description */) expected(U&& v);
 
    template<class G>
      constexpr expected(const unexpected<G>&);
    template<class G>
      constexpr expected(unexpected<G>&&);
 
    template<class... Args>
      constexpr explicit expected(in_place_t, Args&&...);
    template<class U, class... Args>
      constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...);
    template<class... Args>
      constexpr explicit expected(unexpect_t, Args&&...);
    template<class U, class... Args>
      constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);
 
    // destructor
    constexpr ~expected();
 
    // assignment
    constexpr expected& operator=(const expected&);
    constexpr expected& operator=(expected&&) noexcept(/* see description */);
    template<class U = T> constexpr expected& operator=(U&&);
    template<class G>
      constexpr expected& operator=(const unexpected<G>&);
    template<class G>
      constexpr expected& operator=(unexpected<G>&&);
 
    template<class... Args>
      constexpr T& emplace(Args&&...) noexcept;
    template<class U, class... Args>
      constexpr T& emplace(initializer_list<U>, Args&&...) noexcept;
 
    // swap
    constexpr void swap(expected&) noexcept(/* see description */);
    friend constexpr void swap(expected&, expected&) noexcept(/* see description */);
 
    // observers
    constexpr 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&;
    constexpr T& value() &;
    constexpr const T&& value() const&&;
    constexpr T&& value() &&;
    constexpr const E& error() const&;
    constexpr E& error() &;
    constexpr const E&& error() const&&;
    constexpr E&& error() &&;
    template<class U> constexpr T value_or(U&&) const&;
    template<class U> constexpr T value_or(U&&) &&;
    template<class G = E> constexpr E error_or(G&&) const &;
    template<class G = E> constexpr E error_or(G&&) &&;
 
    // 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 &&;
 
    // 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 T2>
      friend constexpr bool operator==(const expected&, const T2&);
    template<class E2>
      friend constexpr bool operator==(const expected&, const unexpected<E2>&);
 
  private:
    bool has_val;       // exposition only
    union {
      T val;            // exposition only
      E unex;           // exposition only
    };
  };
}

Partial specialization of std::expected for void types

namespace std {
  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>;
 
    // constructors
    constexpr expected() noexcept;
    constexpr explicit(/* see description */)
      expected(const expected&);
    constexpr explicit(/* see description */)
      expected(expected&&) noexcept(/* see description */);
    template<class U, class G>
      constexpr explicit(/* see description */) expected(const expected<U, G>&);
    template<class U, class G>
      constexpr explicit(/* see description */) expected(expected<U, G>&&);
 
    template<class G>
      constexpr expected(const unexpected<G>&);
    template<class G>
      constexpr 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&&...);
 
    // destructor
    constexpr ~expected();
 
    // assignment
    constexpr expected& operator=(const expected&);
    constexpr expected& operator=(expected&&) noexcept(/* see description */);
    template<class G>
      constexpr expected& operator=(const unexpected<G>&);
    template<class G>
      constexpr expected& operator=(unexpected<G>&&);
    constexpr void emplace() noexcept;
 
    // swap
    constexpr void swap(expected&) noexcept(/* see description */);
    friend constexpr void swap(expected&, expected&) noexcept(/* see description */);
 
    // observers
    constexpr explicit operator bool() const noexcept;
    constexpr bool has_value() const noexcept;
    constexpr void operator*() const noexcept;
    constexpr void value() const&;
    constexpr void value() &&;
    constexpr const E& error() const&;
    constexpr E& error() &;
    constexpr const E&& error() const&&;
    constexpr E&& error() &&;
    template<class G = E> constexpr E error_or(G&&) const &;
    template<class G = E> constexpr E error_or(G&&) &&;
 
    // 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 &&;
 
    // 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
    };
  };
}