std::expected
来自cppreference.com
在标头 <expected> 定义
|
||
template< class T, class E > class expected; |
(C++23 起) | |
类模板 std::expected
提供存储二个值之一的方式。 std::expected
的对象再任何给定时刻要么保有一个期待的 T
类型值,要么保有一个不期待的 E
类型值。 std::expected
决不会无值。
存储的值直接分配于 expected
对象所占用的存储中。不发生动态分配。
若程序以引用类型、函数类型,或 std::unexpected 的特化实例化 expected
则程序非良构。另外, T
必须不是 std::in_place_t 或 std::unexpect_t 。
模板形参
T | - | 期待的值的类型。类型必须为(可有 cv 限定的) void 或符合可析构 (Destructible) 要求(尤其是不允许数组或引用类型)。 |
E | - | 不期待的值的类型。类型必须符合可析构 (Destructible) 要求,且必须对于 std::unexpected 为合法的模板形参(尤其是不允许数组、非对象类型及 cv 限定的类型)。 |
成员类型
成员类型 | 定义 |
value_type
|
T
|
error_type
|
E
|
unexpected_type
|
std::unexpected<E>
|
rebind
|
template< class U > using rebind = expected<U, error_type>; |
成员函数
构造 expected 对象 (公开成员函数) | |
销毁 expected 对象以及其所含的值 (公开成员函数) | |
(C++23) |
赋值内容 (公开成员函数) |
观察器 | |
返回期待的值 (公开成员函数) | |
检查对象是否含有期待的值 (公开成员函数) | |
返回期待的值 (公开成员函数) | |
返回不期待的值 (公开成员函数) | |
如果有期待的值则返回它,否则返回另一个值 (公开成员函数) | |
单子操作 | |
若期待的值存在则返回给定的函数在其上的结果,否则返回 expected 本身 (公开成员函数) | |
若期待的值存在则返回含有变换后期待的值的 expected ,否则返回 expected 本身 (公开成员函数) | |
若 expected 含有期待的值则返回其自身,否则返回给定的函数在不期待的值上的结果 (公开成员函数) | |
若含有期待的值则返回 expected 本身,否则返回含有变换后不期待的值的 expected (公开成员函数) | |
修改器 | |
在原位构造期待的值 (公开成员函数) | |
交换内容 (公开成员函数) |
非成员函数
比较 expected 对象 (函数模板) | |
(C++23) |
特化 std::swap 算法 (函数) |
辅助类
(C++23) |
表示为不期待的值 (类模板) |
(C++23) |
指示对含有不期待的值的 expected 的有检查访问的异常 (类模板) |
(C++23) |
expected 中不期待的值的原位构造标签 (类) (常量) |
注解
拥有相同功能的类型在 Rust 与 Haskell 中分别被称为 Result
和 Either
。
功能特性测试宏 | 值 | 标准 |
---|---|---|
__cpp_lib_expected |
202202L | (C++23) |
示例
运行此代码
#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); }
输出:
str: "42", value: 42 str: "42abc", value: 42 str: "meow", error: invalid input str: "inf", error: overflow
引用
- C++23 标准(ISO/IEC 14882:2023):
- 22.8 Expected objects [expected]
参阅
(C++17) |
类型安全的可辨识联合体 (类模板) |
(C++17) |
可能或可能不保有一个对象的包装器 (类模板) |