命名空间
变体
操作

std::expected

来自 cppreference.com
< cpp‎ | utility
 
 
实用程序库
语言支持
类型支持 (基本类型,RTTI)
库功能测试宏 (C++20)
动态内存管理
程序实用程序
协程支持 (C++20)
可变参数函数
调试支持
(C++26)
三元比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用实用程序
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (在 C++20 中已弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型操作
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
通用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
expected
(C++23)
基本字符串转换
(C++17)
(C++17)

 
 
定义在头文件 <expected>
template< class T, class E >
class expected;
(1) (自 C++23 起)
template< class T, class E >

    requires std::is_void_v<T>

class expected<T, E>;
(2) (自 C++23 起)

类模板 std::expected 提供了一种表示两种值之一的方法:类型为 T预期值,或类型为 E意外值。std::expected 从不为空。

1) 主模板。在其自己的存储区中包含预期值或意外值。不会进行动态内存分配。
2) void 部分特化。表示预期 void 值,或在其自己的存储区中包含意外值。不会进行动态内存分配。

如果程序实例化具有引用类型、函数类型或 std::unexpected 的特化的 expected,则程序格式错误。此外,T 不能是 std::in_place_tstd::unexpect_t

内容

[编辑] 模板参数

T - 预期值的类型。类型必须是(可能是 cv 限定的)void,或满足 可销毁 要求(特别是,不允许使用数组和引用类型)。
E - 意外值的类型。类型必须满足 可销毁 要求,并且必须是 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
(公有成员函数) [编辑]
修改器
在原地构造预期值
(公有成员函数) [编辑]
交换内容
(公有成员函数) [编辑]

[编辑] 非成员函数

比较expected对象
(函数模板) [编辑]
专门化了std::swap算法
(函数) [编辑]

[编辑] 辅助类

表示为意外值
(类模板) [编辑]
异常指示对包含意外值的expected进行检查访问
(类模板) [编辑]
expected中意外值的原地构造标签
(标签)[编辑]

[编辑] 注释

具有相同功能的类型在 Rust 中被称为Result,在 Haskell 中被称为Either

功能测试 Std 功能
__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++23 标准 (ISO/IEC 14882:2024)
  • 22.8 预期对象 [预期]

[编辑] 另见

(C++17)
类型安全的区分联合
(类模板) [编辑]
(C++17)
可能包含或可能不包含对象的包装器
(类模板) [编辑]