C++23的std::expected是什么_C++中优雅处理函数返回值与错误的现代方法

夏明酱_2487

夏明酱_2487

2025-11-23

707人浏览

原创

c++oding="utf-8" ?>

std::expected 是 c++23 引入的模板类,用于表示操作成功时包含类型为 t 的值,失败时包含类型为 e 的错误信息;2. 它相比异常和错误码更安全高效,能明确传达失败原因且无运行时开销;3. 支持 has_value、error、隐式布尔转换及 and_then、or_else 等链式操作,提升错误处理的可读性与表达力;4. 推荐用于文件读取、网络请求等可能失败的操作,错误类型宜用枚举或轻量结构体;5. 当前 gcc 13+ 和 clang 17+ 在 -std=c++23 下部分支持,msvc 正在跟进,暂不可用时可使用 tl::expected 过渡。

c++23的std::expected是什么_c++中优雅处理函数返回值与错误的现代方法

在C++23中,std::expected 是一种全新的类型,用于更清晰、更安全地处理可能失败的函数调用。它提供了一种比异常和错误码更现代、更直观的方式来表达“期望得到一个值,但也可能得到一个错误”的语义。

什么是 std::expected?

std::expected 是一个模板类,表示要么包含一个类型为 T 的成功值(the expected value),要么包含一个类型为 E 的错误值。这与 std::optional 类似,但不同的是:optional 表示“有值或无值”,而 expected 明确告诉你“为什么没有值”——因为它包含了具体的错误信息。

举个例子:

假设你写一个函数来解析整数:

std::expected<int std::string> parse_int(const std::string& str) {
    try {
        size_t pos;
        int value = std::stoi(str, &pos);
        if (pos != str.size()) {
            return std::unexpected("Invalid: extra characters");
        }
        return value;
    } catch (const std::invalid_argument&) {
        return std::unexpected("Invalid argument");
    } catch (const std::out_of_range&) {
        return std::unexpected("Number out of range");
    }
}
</int>

调用时可以这样处理结果:

auto result = parse_int("123abc");
if (result.has_value()) {
    std::cout 

<h3>相比传统方法的优势</h3>
<p>以往我们常用以下方式处理错误:</p><div class="aritcle_card flexRow artxards">
											<div class="artcardd flexRow">
												<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架"><img
														src="https://img.php.cn/upload/skill/000/000/081/178988956499722.jpg" alt="C++ 算法竞赛自动化测试数据生成与校验框架" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
												<div class="aritcle_card_info flexColumn">
													<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="overflowclass">C++ 算法竞赛自动化测试数据生成与校验框架</a>
													<p class="overflowclass">根据原题生成新题面、验证器及完整测试数据,自动套用 testlib 模板,用于用户要求生成测试数据时。</p>
												</div>
												<a rel="nofollow" href="/xiazai/skill4025" title="C++ 算法竞赛自动化测试数据生成与校验框架" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
												</a>
											</div>
										</div>
  • 返回 bool + 输出参数(不够直观)
  • 抛出异常(开销大,控制流不清晰)
  • 使用 errno 或全局状态(线程不安全)
  • 返回 std::pair 或 std::variant(语义模糊)

std::expected 解决了这些问题:

  • 明确区分成功与失败路径
  • 携带详细的错误信息(不只是 true/false)
  • 零成本抽象:没有异常开销
  • 编译期检查:必须处理错误,否则容易被注意到
  • 支持链式操作,如 and_then、or_else 等(类似函数式编程)

如何有效使用 std::expected

实际开发中,建议这样使用:

  • 对于可能失败但属于正常流程的操作(如文件读取、网络请求、数据解析),优先考虑返回 expected
  • 错误类型 E 推荐使用枚举或轻量错误结构体,避免 string(除非调试需要)
  • 配合 if-else 或 switch 处理分支,代码可读性
  • 利用其隐式布尔转换简化判断:if (auto res = compute(); res) { ... }

还支持一些便捷操作:

// 链式处理
get_user_id()
    .and_then(fetch_user_data)
    .or_else([](const auto& e) {
        log_error(e);
        return default_user();
    });

注意事项与现状

目前(截至主流编译器2024年版本),std::expected 在 GCC 13+、Clang 17+ 中已部分支持,需启用 -std=c++23 并注意标准库实现进度。MSVC 正在跟进。

若暂不可用,可使用 TL::expected 第三方库作为过渡,接口高度兼容。

基本上就这些。std::expected 让 C++ 的错误处理变得更直接、更可靠,是现代 C++ 值得掌握的重要工具。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

2023.08.02

4999

3

switch语句用法
switch语句用法

switch语句用法:1、Switch语句只能用于整数类型,枚举类型和String类型,不能用于浮点数类型和布尔类型;2、每个case语句后面必须跟着一个break语句,以防止执行其他case的代码块,没有break语句,将会继续执行下一个case的代码块;3、可以在一个case语句中匹配多个值,使用逗号分隔;4、Switch语句中的default代码块是可选的等等。

2023.09.21

1011

6

Java switch的用法
Java switch的用法

Java中的switch语句用于根据不同的条件执行不同的代码块。想了解更多switch的相关内容,可以阅读本专题下面的文章。

2024.03.13

1337

13

scripterror怎么解决
scripterror怎么解决

scripterror的解决办法有检查语法、文件路径、检查网络连接、浏览器兼容性、使用try-catch语句、使用开发者工具进行调试、更新浏览器和JavaScript库或寻求专业帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.18

869

5

500error怎么解决
500error怎么解决

500error的解决办法有检查服务器日志、检查代码、检查服务器配置、更新软件版本、重新启动服务、调试代码和寻求帮助等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.25

2260

5

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

2025.06.09

3814

18

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

2025.07.04

3971

25

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

2023.10.19

3028

3

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

2025.10.17

4169

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Fiber框架快速入门指南
Fiber框架快速入门指南

共0课时 | 0人学习

Fiber框架两小时速通教程
Fiber框架两小时速通教程

共0课时 | 0人学习