首页 > 后端开发 > C++ > 正文

C++23中的std::expected怎么用_C++错误处理与std::expected使用

裘德小鎮的故事
发布: 2025-11-09 09:38:03
原创
239人浏览过
std::expected<T, E> 是C++23引入的用于显式处理预期错误的类型,它能安全携带成功值或错误信息。相比异常和 optional,它避免了异常开销且能表达具体错误原因。通过 .has_value()、.value()、.error() 等方法可安全访问结果,支持默认值回退和链式判断,适用于除法、字符串解析等可能失败的操作,提升代码健壮性。

c++23中的std::expected怎么用_c++错误处理与std::expected使用

在C++23中,std::expected 被正式引入作为处理预期结果或错误的标准化方式。它比传统的异常和返回码更灵活、更安全,尤其适合那些可能失败但又不值得抛出异常的函数。

什么是 std::expected?

std::expected<T, E> 是一个模板类,表示一个操作要么成功并返回类型为 T 的值,要么失败并返回类型为 E 的错误信息。这与 std::optional<T> 类似,但它不仅能表达“无值”,还能携带具体的错误原因。

举个例子:一个除法函数可以返回结果,也可以返回一个错误码说明“除零”:

#include <expected>
#include <iostream>

enum class MathError {
    DivisionByZero
};

std::expected<double, MathError> divide(double a, double b) {
    if (b == 0.0) {
        return std::unexpected(MathError::DivisionByZero);
    }
    return a / b;
}
登录后复制

调用时可以清晰地判断是否成功:

立即学习C++免费学习笔记(深入)”;

auto result = divide(10, 0);
if (result.has_value()) {
    std::cout << "Result: " << result.value() << "\n";
} else {
    std::cout << "Error: Division by zero\n";
}
登录后复制

如何检查结果和提取值?

std::expected 提供了几种方式来访问内部值或处理错误:

  • .has_value():判断是否包含正常值
  • .value():获取值,若无值则抛出异常(基于 E 构造)
  • .error():当出错时,获取错误对象
  • .value_or(default):有值则返回,否则返回默认值(仅当 E 可构造时可用)

示例:

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店 56
查看详情 AppMall应用商店
auto res = divide(5, 2);
if (res) {
    std::cout << res.value(); // 输出 2.5
} else {
    if (res.error() == MathError::DivisionByZero) {
        std::cout << "Cannot divide by zero.";
    }
}
登录后复制

与异常和 optional 的对比

相比传统方式,std::expected 更明确地表达了“可预期的失败”:

  • 异常:开销大,控制流跳转隐式,不适合高频调用或性能敏感场景
  • std::optional:只能表示“有/无”,无法说明为何失败
  • std::expected:显式携带错误信息,不依赖异常机制,类型安全

比如解析字符串为整数:

std::expected<int, std::string> try_parse_int(const std::string& s) {
    try {
        size_t pos;
        int value = std::stoi(s, &pos);
        if (pos != s.size()) {
            return std::unexpected("Invalid characters at end");
        }
        return value;
    } catch (...) {
        return std::unexpected("Parse failed");
    }
}
登录后复制

链式处理与 map/or_else 模式(模拟)

虽然 C++23 标准库未直接提供 mapand_then 方法,但你可以手动组合使用。

例如连续解析两个数并相加:

auto a = try_parse_int("42");
auto b = try_parse_int("abc");

if (a && b) {
    std::cout << "Sum: " << (a.value() + b.value()) << "\n";
} else {
    if (!a) std::cout << "First parse failed: " << a.error() << "\n";
    if (!b) std::cout << "Second parse failed: " << b.error() << "\n";
}
登录后复制

你也可以封装辅助函数实现类似函数式风格的处理逻辑。

基本上就这些。std::expected 让错误处理变得更直观、更安全,尤其是在系统编程、配置解析、IO操作等常见场景中非常实用。不复杂但容易忽略细节,比如正确使用 std::unexpected 来包装错误。用好它,代码会更健壮。

以上就是C++23中的std::expected怎么用_C++错误处理与std::expected使用的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号