TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

C++23中的std::expected:现代C++错误处理新范式

2025-12-23
/
0 评论
/
34 阅读
/
正在检测是否收录...
12/23

在C++的发展历程中,错误处理始终是开发者面临的挑战之一。从传统的错误码到异常机制,再到C++23引入的std::expected,语言不断演进以提供更安全、更直观的解决方案。本文将带你深入理解std::expected的设计哲学,并通过实际代码示例展示其强大功能。

1. 为什么需要std::expected?

传统C++错误处理主要有两种方式:
- 错误码:通过返回值或输出参数传递错误状态,但容易与正常逻辑混淆。
- 异常:虽能分离错误路径,但性能开销和复杂性常令人却步。

std::expected<T, E>应运而生,它封装了可能成功的结果(T)或错误(E),提供类型安全的统一接口,同时避免异常的开销。其核心思想源自函数式编程中的Either模式。

2. 基本用法

std::expected定义在<expected>头文件中,其声明如下:

template<class T, class E>
class expected;
示例1:简单返回值与错误
#include <expected>
#include <string>

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

int main() {
    auto result = parse_number("42");
    if (result) {
        std::cout << "Value: " << *result << "\n"; // 解引用获取值
    } else {
        std::cerr << "Error: " << result.error() << "\n";
    }
}

关键点
- operator bool检查是否包含有效值。
- operator*value()获取值(若无效则行为未定义)。
- error()获取错误对象。

3. 高级特性

链式操作:and_then/or_else

std::expected支持函数式风格的链式调用:

std::expected<int, std::string> safe_divide(int a, int b) {
    if (b == 0) return std::unexpected{"Division by zero"};
    return a / b;
}

void demo_chain() {
    parse_number("10")
        .and_then([](int n) { return safe_divide(n, 2); })
        .transform([](int q) { return q * 100; })
        .or_else([](auto err) { 
            std::cerr << "Failed: " << err << "\n";
            return std::expected<int, std::string>{0}; 
        });
}
性能优势

与异常相比,std::expected无堆栈展开开销;与错误码相比,它强制开发者显式处理错误,避免遗漏。

4. 对比其他方案

| 方案 | 优点 | 缺点 |
|----------------|----------------------|----------------------|
| 错误码 | 简单、零开销 | 易忽略检查 |
| 异常 | 分离错误路径 | 性能不稳定 |
| std::expected | 类型安全、显式处理 | 语法稍复杂 |

5. 实际应用场景

  • 文件操作:返回文件内容或错误详情。
  • 网络请求:处理HTTP状态码与响应体。
  • 解析器:组合多个可能失败的操作。

结语

错误处理C++23异常替代返回值std::expected
朗读
赞(0)
版权属于:

至尊技术网

本文链接:

https://www.zzwws.cn/archives/42262/(转载时请注明本文出处及文章链接)

评论 (0)
37,548 文章数
92 评论量

人生倒计时

今日已经过去小时
这周已经过去
本月已经过去
今年已经过去个月