std::expected

From cppreference.com
< cpp‎ | utility
 
 
Utilities library
General utilities
Relational operators (deprecated in C++20)
 
 
Defined in header <expected>
template< class T, class E >
class expected;
(1) (since C++23)
template< class T, class E >

    requires std::is_void_v<T>

class expected<T, E>;
(2) (since C++23)

The class template std::expected provides a way to represent either of two values: an expected value of type T, or an unexpected value of type E. std::expected is never valueless.

1) The main template. Contains the expected or unexpected value within its own storage. No dynamic memory allocation takes place.
2) The void partial specialization. Represents an expected void value or contains the unexpected value within its own storage. No dynamic memory allocation takes place.

A program is ill-formed if it instantiates an expected with a reference type, a function type, or a specialization of std::unexpected. In addition, T must not be std::in_place_t or std::unexpect_t.

Template parameters

T - the type of the expected value. The type must either be (possibly cv-qualified) void, or meet the Destructible requirements (in particular, array and reference types are not allowed).
E - the type of the unexpected value. The type must meet the Destructible requirements, and must be a valid template argument for std::unexpected (in particular, arrays, non-object types, and cv-qualified types are not allowed).

Member types

Member type Definition
value_type T
error_type E
unexpected_type std::unexpected<E>

Member alias templates

Type Definition
rebind<U> std::expected<U, error_type>

Data members

Member Definition
bool has_val whether the expected object currently represents the expected value
(exposition-only member object*)
T val (main template only) the expected value
(exposition-only variant member object*)
E unex the unexpected value
(exposition-only variant member object*)

Member functions

constructs the expected object
(public member function)
destroys the expected object, along with its contained value
(public member function)
assigns contents
(public member function)
Observers
accesses the expected value
(public member function)
checks whether the object contains an expected value
(public member function)
returns the expected value
(public member function)
returns the unexpected value
(public member function)
returns the expected value if present, another value otherwise
(public member function)
returns the unexpected value if present, another value otherwise
(public member function)
Monadic operations
returns the result of the given function on the expected value if it exists; otherwise, returns the expected itself
(public member function)
returns an expected containing the transformed expected value if it exists; otherwise, returns the expected itself
(public member function)
returns the expected itself if it contains an expected value; otherwise, returns the result of the given function on the unexpected value
(public member function)
returns the expected itself if it contains an expected value; otherwise, returns an expected containing the transformed unexpected value
(public member function)
Modifiers
constructs the expected value in-place
(public member function)
exchanges the contents
(public member function)

Non-member functions

compares expected objects
(function template)
specializes the std::swap algorithm
(function)

Helper classes

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)

Notes

Types with the same functionality are called Result in Rust and Either in Haskell.

Feature-test macro Value Std Feature
__cpp_lib_expected 202202L (C++23) class template std::expected and associated helper classes
202211L (C++23) Monadic functions for std::expected

Example

#include <cmath>
#include <expected>
#include <iomanip>
#include <iostream>
#include <string_view>
 
enum class parse_error
{
    invalid_input,
    overflow
};
 
auto parse_number(std::string_view& str) -> std::expected<double, parse_error>
{
    const char* begin = str.data();
    char* end;
    double retval = std::strtod(begin, &end);
 
    if (begin == end)
        return std::unexpected(parse_error::invalid_input);
    else if (std::isinf(retval))
        return std::unexpected(parse_error::overflow);
 
    str.remove_prefix(end - begin);
    return retval;
}
 
int main()
{
    auto process = [](std::string_view str)
    {
        std::cout << "str: " << std::quoted(str) << ", ";
        if (const auto num = parse_number(str); num.has_value())
            std::cout << "value: " << *num << '\n';
            // If num did not have a value, dereferencing num
            // would cause an undefined behavior, and
            // num.value() would throw std::bad_expected_access.
            // num.value_or(123) uses specified default value 123.
        else if (num.error() == parse_error::invalid_input)
            std::cout << "error: invalid input\n";
        else if (num.error() == parse_error::overflow)
            std::cout << "error: overflow\n";
        else
            std::cout << "unexpected!\n"; // or invoke std::unreachable();
    };
 
    for (auto src : {"42", "42abc", "meow", "inf"})
        process(src);
}

Output:

str: "42", value: 42
str: "42abc", value: 42
str: "meow", error: invalid input
str: "inf", error: overflow

References

  • C++23 standard (ISO/IEC 14882:2024):
  • 22.8 Expected objects [expected]

See also

(C++17)
a type-safe discriminated union
(class template)
(C++17)
a wrapper that may or may not hold an object
(class template)