0

0

c++怎么使用C++23的std::expected进行错误处理_C++23新特性与安全错误处理

下次还敢

下次还敢

发布时间:2025-11-16 16:18:57

|

403人浏览过

|

来源于php中文网

原创

std::expected是C++23引入的用于安全处理可能失败操作的模板类,它封装成功值或错误信息,提供类型安全、显式错误处理,避免异常开销,适用于嵌入式与高可靠性场景。

c++怎么使用c++23的std::expected进行错误处理_c++23新特性与安全错误处理

在C++23中,std::expected 被正式引入作为标准库的一部分,用于更安全、更清晰地处理可能失败的操作。它提供了一种类型安全的方式来表示一个值或一个错误,取代传统的异常抛出或返回错误码的方式,尤其适合在不希望使用异常的项目中进行可靠错误处理。

什么是 std::expected?

std::expected 是一个模板类,表示要么包含一个类型为 T 的期望值(成功情况),要么包含一个类型为 E 的错误信息(失败情况)。这类似于函数式语言中的 Result 类型,也与 std::optional 类似,但能携带具体的错误原因,而不仅仅是“有值”或“无值”。

相比以下方式:

  • 用返回值表示结果,通过输出参数带回错误码 —— 不直观且易出错
  • 抛出异常 —— 在禁用异常的环境(如嵌入式)不可用,性能开销大
  • 使用 std::optional + 全局错误状态 —— 无法传递具体错误信息

std::expected 提供了更现代、更安全的替代方案。

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

基本用法示例

下面是一个使用 std::expected 实现整数除法的简单例子:

#include 
#include 
#include 

std::expected divide(int a, int b) { if (b == 0) { return std::unexpected("除数不能为零"); } return a / b; }

int main() { auto result = divide(10, 2); if (result.has_value()) { std::cout << "结果: " << result.value() << "\n"; } else { std::cout << "错误: " << result.error() << "\n"; }

auto bad_result = divide(10, 0);
if (!bad_result) {
    std::cout zuojiankuohaophpcnzuojiankuohaophpcn "错误: " zuojiankuohaophpcnzuojiankuohaophpcn bad_result.error() zuojiankuohaophpcnzuojiankuohaophpcn "\n";
}

}

在这个例子中:

  • 成功时返回 std::expected 包含结果值
  • 失败时通过 std::unexpected(err) 构造错误分支
  • 使用 has_value()隐式转换判断是否成功
  • 通过 .value() 获取正常值,.error() 获取错误信息

错误类型的选取建议

选择合适的错误类型 E 很重要。常见做法包括:

Civitai
Civitai

AI艺术分享平台!海量SD资源和开源模型。

下载
  • 使用枚举类型(如 enum class ErrorCode)提高性能和类型安全
  • 使用 std::stringstd::string_view 方便调试和日志输出
  • 结合 std::error_code 与自定义错误类别,实现与现有系统集成

例如:

enum class ParseError {
    InvalidSyntax,
    Overflow
};

std::expected parse_int(const std::string& str) { // ... 解析逻辑 if (/ 格式错误 /) { return std::unexpected(ParseError::InvalidSyntax); } if (/ 溢出 /) { return std::unexpected(ParseError::Overflow); } return parsed_value; }

链式操作与映射错误

虽然当前标准尚未提供像 .and_then().or_else() 这样的函数式组合方法(预计后续标准加入),但你可以手动实现简洁的链式调用:

auto result = compute_a();
if (!result) return result;

auto next = compute_b(result.value()); if (!next) return std::unexpected(next.error());

return next;

也可以封装辅助宏或工具函数来简化处理流程,提升代码可读性

与异常的对比与选择

std::expected 并非要完全取代异常,而是提供另一种选择:

  • 当你希望错误处理显式可见、编译期检查时,用 expected
  • 当错误是真正异常的、罕见的情况,且项目允许异常时,仍可用 throw/catch
  • 在资源受限或禁用异常的环境中,expected 是更优解

它的优势在于:

  • 零成本抽象:没有异常机制的运行时开销
  • 强制错误检查:调用者必须处理失败可能
  • 支持移动语义和任意可构造类型

基本上就这些。std::expected 让 C++ 的错误处理更加现代化和安全,特别适合系统编程、库开发和高可靠性场景。

相关专题

更多
string转int
string转int

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

312

2023.08.02

scripterror怎么解决
scripterror怎么解决

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

184

2023.10.18

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

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

265

2023.10.25

string转int
string转int

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

312

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

522

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

49

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

190

2025.08.29

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

459

2024.01.03

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

74

2025.12.31

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 3.2万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

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