22 General utilities library [utilities]
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>;
    
    constexpr expected();
    constexpr expected(const expected&);
    constexpr expected(expected&&) noexcept(see below);
    template<class U, class G>
      constexpr explicit(see below) expected(const expected<U, G>&);
    template<class U, class G>
      constexpr explicit(see below) expected(expected<U, G>&&);
    template<class U = T>
      constexpr explicit(see below) expected(U&& v);
    template<class G>
      constexpr explicit(see below) expected(const unexpected<G>&);
    template<class G>
      constexpr explicit(see below) expected(unexpected<G>&&);
    template<class... Args>
      constexpr explicit expected(in_place_t, Args&&...);
    template<class U, class... Args>
      constexpr explicit expected(in_place_t, initializer_list<U>, Args&&...);
    template<class... Args>
      constexpr explicit expected(unexpect_t, Args&&...);
    template<class U, class... Args>
      constexpr explicit expected(unexpect_t, initializer_list<U>, Args&&...);
    
    constexpr ~expected();
    
    constexpr expected& operator=(const expected&);
    constexpr expected& operator=(expected&&) noexcept(see below);
    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;
    
    constexpr void swap(expected&) noexcept(see below);
    friend constexpr void swap(expected& x, expected& y) noexcept(noexcept(x.swap(y)));
    
    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 & noexcept;
    constexpr E& error() & noexcept;
    constexpr const E&& error() const && noexcept;
    constexpr E&& error() && noexcept;
    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&&) &&;
    
    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 &&;
    
    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;       
    union {
      T val;            
      E unex;           
    };
  };
}
Any object of type 
expected<T, E> either
contains a value of type 
T or
a value of type 
E within its own storage
.Implementations are not permitted to use additional storage,
such as dynamic memory,
to allocate the object of type 
T or the object of type 
E.Member 
has_val indicates whether the 
expected<T, E> object
contains an object of type 
T.A type 
T is a 
valid value type for expected,
if 
remove_cv_t<T> is 
void
or a complete non-array object type that is not 
in_place_t,
unexpect_t,
or a specialization of 
unexpected.A program which instantiates class template 
expected<T, E>
with an argument 
T that is not a valid value
type for 
expected is ill-formed
.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
.When 
T is not 
cv void, it shall meet
the 
Cpp17Destructible requirements (Table 
35)
.E shall meet
the 
Cpp17Destructible requirements
.