通八洲科技

c++23中的std::expected是什么以及如何使用_c++错误处理新方案详解

日期:2025-11-14 00:00 / 作者:尼克
std::expected是C++23引入的模板类,用于显式表示操作可能返回T类型值或E类型错误,相比错误码和异常更安全高效。它通过has_value()、value()、error()等成员函数提供清晰的错误处理机制,并支持and_then、or_else、transform等链式组合操作,使错误处理更现代、类型安全且无需异常开销。

std::expected 是 C++23 引入的一个新类型,用于更清晰、更安全地处理可能失败的操作。它提供了一种比异常和错误码更现代的错误处理方式,尤其适合函数可能返回正常值或错误信息的场景。

什么是 std::expected?

std::expected 是一个模板类,表示“期望得到一个 T 类型的值,但可能会得到一个 E 类型的错误”。它类似于 std::optional(可能有值或无值),但不同之处在于:当没有正常值时,它不是“空”,而是包含一个具体的错误对象(E 类型)。

这使得调用者能明确知道操作失败的原因,而不是仅仅判断“有没有结果”。

与传统错误处理方式对比

• 返回错误码:需要额外的输出参数或全局变量(如 errno),容易忽略检查。
• 抛出异常:性能开销大,控制流不明显,不适合高频调用或系统级代码。
• std::optional:只能表达“有值/无值”,无法说明为何无值。
• std::expected:既能返回成功值,也能携带具体错误,类型安全且无需异常支持。

基本使用方法

假设我们要实现一个除法函数,可能因除零而失败:

#include 
#include

enum class DivideError {
DivisionByZero
};

std::expected divide(double a, double b) {
if (b == 0.0) {
return std::unexpected(DivideError::DivisionByZero);
}
return a / b;
}

int main() {
auto result = divide(10.0, 2.0);
if (result.has_value()) {
std::cout << "Result: " << result.value() << "\\n";
} else {
std::cout << "Error: Division by zero\\n";
}

auto bad_result = divide(5.0, 0.0);
if (!bad_result) {
if (bad_result.error() == DivideError::DivisionByZero) {
std::cout << "Caught division by zero\\n";
}
}
return 0;
}

关键成员函数:
• has_value():检查是否包含正常值。
• value():获取成功值(若无值则抛异常,慎用)。
• operator*:解引用获取值(需确保有值)。
• error():获取错误对象。
• operator bool():可直接用于条件判断。

链式处理与辅助操作

可以结合 lambda 或函数指针做链式调用,类似 Rust 的 ? 操作符思想:

std::expected parse_number(const std::string& s) {
try {
return std::stoi(s);
} catch (...) {
return std::unexpected("Invalid number format");
}
}

auto result = parse_number("42")
.and_then([](int n) -> std::expected {
if (n < 0) return std::unexpected("Negative not allowed");
return n * 2;
});

if (result) {
std::cout << "Parsed and doubled: " << *result << "\\n";
} else {
std::cout << "Error: " << result.error() << "\\n";
}

常用组合方法:
• and_then(func):值存在时执行转换函数。
• or_else(func):值不存在时提供回退逻辑。
• transform(func):对值进行映射(返回 expected)。

基本上就这些。std::expected 让错误处理变得显式、类型安全且易于组合,是 C++23 中值得掌握的新特性。