When I looked at the compiler support for cppreference recently, I found that libstdc++ already implements <expected>
, but unfortunately I didn’t find much information about it on the web.
What is std::expected
?
It is similar to std::optional
, but std::optional
can only indicate a normal value or std::nullopt
, i.e. a null value. In contrast, std::expected
can indicate an expected value and an error value, which is equivalent to the two-member std::variant
, but is more convenient to use on the interface. Think of it as a new kind of error handling.
Basic use
Constructs
std::expected<T,E>
has two template arguments, the first indicating the expected value and the second indicating the wrong value.
If it is the expected value, there is an implicit conversion.
|
|
If it is an exception, it is initialized by std::expected()
.
|
|
default constructor
|
|
Requires S
to have a default constructor
, otherwise an exception will be thrown.
Usage
Same pointer semantics as std::optional
, can be dereferenced.
Note that you must check before unquoting, otherwise it is UB!!!
The following is equivalent in effect to the above.
Note that std::expected<T,E>::value()
throws an exception if the value does not exist, which is somewhat safer.
Indicates an error
If not used incorrectly as UB!!!
If the result returned is said to be an error, a default value can be provided more elegantly with value_or()
.
Internal implementation
The implementation of std::expected<T,E>
is relatively simple and does not rely on any new language features. It consists of an expected value of type T
and a union of std::unexpected<E>
and a bool
value indicating whether it is an error or not. The rest are some helper
functions.