Some low-level code could benefit from being able to use std::expected from C++23:
- Currently, some code is using
std::optional<E>to denote an optional error. This is fine, but a bit confusing, becausestd::optionalis normally used for values, not errors. Usingstd::expected<void, E>is clearer. - Currently, some code is using
std::variant<V, E>to denote either a value or an error. This is fine, but a bit verbose, becausestd::variantrequires a visitor or get_if/holds_alternative instead of a simple call of theoperator boolforstd::expected.
In theory, util::Result could be taught to behave similar to std::expected (see #34005). However, it is unclear if this is the right approach:
util::Resultis mostly meant for higher level code, where errors come with translated error messages.std::expectedis mostly meant for lower level code, where errors could be an enum, or any other type.- #25665 aims to minimize the memory footprint of the error by wrapping it in a unique_ptr internally.
std::expectedrequires the value and error to be “nested within it” (https://cplusplus.github.io/LWG/issue4141). So from a memory-layout perspective, the two are not compatible. std::expectedalso comes withstd::unexpected, which also does not map cleanly toutil::Result.
So just add a minimal drop-in port of std::expected.