std::expected
来自 cppreference.cn
定义于头文件 <expected> |
||
template< class T, class E > class expected; |
(1) | (C++23 起) |
template< class T, class E > requires std::is_void_v<T> |
(2) | (C++23 起) |
类模板 std::expected
提供了一种表示两种值之一的方式:一个类型为 T
的*预期*值,或一个类型为 E
的*非预期*值。expected
永远不会是无值的。
2) void 偏特化。表示一个预期的 void 值或包含一个非预期值。如果它包含一个非预期值,则该值嵌套在
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<U> | std::expected<U, error_type> |
[编辑] 数据成员
成员 | 定义 |
bool has_val |
expected 对象当前是否表示预期值(仅用于阐释的成员对象*) |
T val (仅限主模板) |
预期值 (仅作说明的变体成员对象*) |
E unex |
非预期值 (仅作说明的变体成员对象*) |
[编辑] 成员函数
构造 expected 对象(公共成员函数) | |
销毁 expected 对象及其包含的值(公共成员函数) | |
赋值内容 (公共成员函数) | |
观察器 | |
访问预期值 (公共成员函数) | |
检查对象是否包含预期值 (公共成员函数) | |
返回预期值 (公共成员函数) | |
返回非预期值 (公共成员函数) | |
如果存在,返回预期值;否则返回另一个值 (公共成员函数) | |
如果存在,返回非预期值;否则返回另一个值 (公共成员函数) | |
Monadic operations | |
如果预期值存在,返回给定函数作用于预期值的结果;否则返回 expected 自身(公共成员函数) | |
如果预期值存在,返回包含转换后的预期值的 expected ;否则返回 expected 自身(公共成员函数) | |
如果 expected 包含预期值,返回 expected 自身;否则返回给定函数作用于非预期值的结果(公共成员函数) | |
如果 expected 包含预期值,返回 expected 自身;否则返回包含转换后的非预期值的 expected (公共成员函数) | |
修改器 | |
就地构造预期值 (公共成员函数) | |
交换内容 (公共成员函数) |
[编辑] 非成员函数
(C++23) |
比较 expected 对象(函数模板) |
(C++23) |
特化 std::swap 算法 (函数) |
[编辑] 辅助类
(C++23) |
表示为意外值 (类模板) |
(C++23) |
表示对包含非预期值的 expected 进行检查访问时抛出的异常(类模板) |
(C++23) |
用于 expected 中非预期值就地构造的标签(标签) |
[编辑] 注
在 Rust 中,具有相同功能的类型称为 Result
;在 Haskell 中,称为 Either
。
特性测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__cpp_lib_expected |
202202L |
(C++23) | 类模板 std::expected 及相关 辅助类 |
202211L |
(C++23) | std::expected 的单子函数 |
[编辑] 示例
运行此代码
#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++ 标准。
缺陷报告 | 应用于 | 发布时的行为 | 正确的行为 |
---|---|---|---|
LWG 4141 | C++23 | 存储要求 令人困惑 |
包含的对象必须 嵌套在 expected 对象内 |
[编辑] 参考
- C++23 标准 (ISO/IEC 14882:2024)
- 22.8 预期对象 [expected]
[编辑] 另请参阅
(C++17) |
一种类型安全的带判别联合体 (类模板) |
(C++17) |
可能包含或不包含对象的包装器 (类模板) |