std:: expected
|
定义于头文件
<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
永远不处于无值状态。
expected
对象内部。
若程序实例化
expected
时使用引用类型、函数类型或
std::unexpected
的特化,则该程序非良构。此外,
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
对象及其包含的值
(公开成员函数) |
|
|
赋值内容
(公开成员函数) |
|
观察器 |
|
|
访问期望值
(公开成员函数) |
|
|
检查对象是否包含期望值
(公开成员函数) |
|
|
返回期望值
(公开成员函数) |
|
|
返回非期望值
(公开成员函数) |
|
|
若存在则返回期望值,否则返回另一值
(公开成员函数) |
|
|
若存在则返回非期望值,否则返回另一值
(公开成员函数) |
|
单子操作 |
|
若期望值存在则返回给定函数对其的处理结果;否则返回
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
的 Monadic 函数
|
示例
#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'; // 如果 num 没有值,解引用 num 将导致未定义行为, // 而 num.value() 会抛出 std::bad_expected_access。 // num.value_or(123) 使用指定的默认值 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"; // 或调用 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 对象 [expected]
参见
|
(C++17)
|
类型安全的可辨识联合体
(类模板) |
|
(C++17)
|
可能持有或未持有对象的包装器
(类模板) |