template< class T, class E >
class expected;
requires std::is_void_v<T>
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
. expected
is never valueless.
The main template. Contains the expected or unexpected value within its own storage, which is
nested withinthe
expected
object.
2) The void partial specialization. Represents an expected void value or contains an unexpected value. If it contains an unexpected value, it is nested within the expected
object.
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.
has_val
whether the expected
object currently represents the expected value
T
val
(main template only) the expected value
E
unex
the unexpected value
expected
object
expected
object, along with its contained value
expected
itself
expected
containing the transformed expected value if it exists; otherwise, returns the expected
itself
expected
itself if it contains an expected value; otherwise, returns the result of the given function on the unexpected value
expected
itself if it contains an expected value; otherwise, returns an expected
containing the transformed unexpected value
Types with the same functionality are called Result
in Rust and Either
in Haskell.
#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[edit] Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR Applied to Behavior as published Correct behavior LWG 4141 C++23 the requirement of storageexpected
object [edit] References
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4