跳到主要内容
版本:Next

expected

std::expected 是 C++23 引入的类型,表示"要么包含一个期望值,要么包含一个错误"。它类似 Rust 的 Result<T, E>,是比异常和 optional 更好的函数返回错误方式。

头文件与基本特征

#include <expected>
特征说明
角色值或错误,二者必居其一
类比Rust Result<T, E>
与 optional 区别optional<T> 只表示"T 或空",expected<T, E> 表示"T 或错误 E"
访问值value()*,有错误时 value() 抛异常
访问错误error()
单子操作and_then(), or_else(), transform() 函数式链式调用

基本用法

#include <expected>
#include <iostream>
#include <string>

enum class Error { Invalid, Overflow };

std::expected<int, Error> divide(int a, int b) {
if (b == 0) return std::unexpected(Error::Invalid);
if (a == INT_MIN && b == -1) return std::unexpected(Error::Overflow);
return a / b;
}

int main() {
auto r1 = divide(10, 2);
auto r2 = divide(10, 0);

if (r1.has_value()) {
std::cout << "result = " << r1.value() << '\n'; // 5
}

if (!r2.has_value()) {
std::cout << "error!\n";
}

// 带默认值
int safe = r2.value_or(-1); // -1

return 0;
}

单子链式操作(Monadic)

C++23 为 expected 提供了单子操作,可以链式调用,避免层层 if 判断:

auto result = divide(10, 2)
.transform([](int x) { return x * 2; }) // 值 → 映射
.and_then([](int x) { return divide(x, 5); }) // 值 → 可能失败
.or_else([](Error e) { // 错误 → 恢复
return 0;
});

常用接口

接口作用
has_value()是否包含期望值
value()获取值,有错误抛 std::bad_expected_access
error()获取错误
value_or(default)有值则返回,否则返回默认值
operator* / operator->访问值(不检查)
transform(fn)对值做映射
and_then(fn)对值做可能失败的操作
or_else(fn)处理错误
std::unexpected(e)构造错误状态

使用注意

  1. expected 是基于栈的,没有动态分配。
  2. 错误类型可以是任意类型(枚举、结构体、std::error_code 等)。
  3. 不要用 expected 替代所有异常——只在"预期内的、可恢复的"错误场景使用。
  4. * 取值为未定义行为,用前先 has_value() 检查。

小结

std::expected<T, E> 是 C++23 中最期待的类型之一。它让"函数可能失败"成为类型签名的一部分,链式调用消除嵌套 if。配合 std::error_code 做错误类型,是 C++ 错误处理的现代化方向。