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对象当前是否表示预期值(仅用于阐释的成员对象*) | 
| Tval(仅限主模板) | 预期值 (仅作说明的变体成员对象*) | 
| Eunex | 非预期值 (仅作说明的变体成员对象*) | 
[编辑] 成员函数
| 构造 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) | 可能包含或不包含对象的包装器 (类模板) | 


