std::expected
From cppreference.com
Defined in header <expected>
|
||
template< class T, class E > class expected; |
(since C++23) | |
The class template std::expected
provides a way to store either of two values. An object of std::expected
at any given time either holds an expected value of type T
, or an unexpected value of type E
. std::expected
is never valueless.
The stored value is allocated directly within the storage occupied by the expected
object. 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 (C++23)
|
T
|
error_type (C++23)
|
E
|
unexpected_type (C++23)
|
std::unexpected<E>
|
rebind (C++23)
|
template< class U > using rebind = expected<U, error_type>; |
Member functions
(C++23) |
constructs the expected object (public member function) |
(C++23) |
destroys the expected object, along with its contained value (public member function) |
(C++23) |
assigns contents (public member function) |
Observers | |
(C++23) |
accesses the expected value (public member function) |
(C++23) |
checks whether the object contains an expected value (public member function) |
(C++23) |
returns the expected value (public member function) |
(C++23) |
returns the unexpected value (public member function) |
(C++23) |
returns the expected value if present, another value otherwise (public member function) |
Monadic operations | |
(C++23) |
returns the result of the given function on the expected value if it exists; otherwise, returns the expected itself (public member function) |
(C++23) |
returns an expected containing the transformed expected value if it exists; otherwise, returns the expected itself (public member function) |
(C++23) |
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) |
(C++23) |
returns the expected itself if it contains an expected value; otherwise, returns an expected containing the transformed unexpected value (public member function) |
Modifiers | |
(C++23) |
constructs the expected value in-place (public member function) |
(C++23) |
exchanges the contents (public member function) |
Non-member functions
(C++23) |
compares expected objects (function template) |
(C++23) |
specializes the std::swap algorithm (function) |
Helper classes
(C++23) |
represented as an unexpected value (class template) |
(C++23) |
exception indicating checked access to an expected that contains an unexpected value (class template) |
(C++23) |
in-place construction tag for unexpected value in expected (class) (constant) |
Notes
Types with the same functionality are called Result
in Rust and Either
in Haskell.
Feature-test macro | Value | Std | Comment |
---|---|---|---|
__cpp_lib_expected |
202202L | (C++23) | class template std::expected and associated helper classes
|
202211L | (C++23) | Monadic functions for std::expected
|
Example
Run this code
#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:2023):
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) |