当前位置: 首页 > news >正文

泉州建设网站的公司安徽省招标投标信息网官方网站

泉州建设网站的公司,安徽省招标投标信息网官方网站,温州网上推广什么网站好,wordpress控制api使用次数C23 引入的一个模板类,用于显式表示可能成功返回一个值或失败返回一个错误的操作。它结合了类型安全和错误处理的优点,是传统错误码(error code)和异常(exceptions)的替代方案。 错误处理的逻辑关系为条件关…

        C++23 引入的一个模板类,用于显式表示可能成功返回一个值或失败返回一个错误的操作。它结合了类型安全和错误处理的优点,是传统错误码(error code)和异常(exceptions)的替代方案。

        错误处理的逻辑关系为条件关系,若正确,则执行A 逻辑;若失败,则执行B 逻辑,并需要知
道确切的错误信息,才能对症下药。当前的常用方式是通过错误码或异常,但使用起来还是多有不
便。
std::expected<T, E> 表示期望,算是std::variant 和std::optional 的结合,它要么保留T(期望的类型),要么保留E(错误的类型),它的接口又和std::optional 相似。

核心概念

  • 设计目标:显式表示可能失败的操作,避免隐式错误处理(如异常)或全局错误码的弊端。

  • 两种状态

    • 预期值(Expected Value):操作成功时存储的返回值。

    • 错误(Error):操作失败时存储的错误信息。

  • 类型安全:错误和成功值的类型在编译时确定,避免运行时类型错误。

std::expected

在标头 <expected> 定义

template< class T, class E >
class expected;

(1)(C++23 起)
template< class T, class E >

    requires std::is_void_v<T>

class expected<T, E>;
(2)(C++23 起)

类模板 std::expected 提供表示两个值之一的方式:它要么表示一个 T 类型的预期 值,要么表示一个 E 类型的非预期 值。expected 决不会无值。

1) 主模板。在自身的存储中包含预期值或非预期值,该值内嵌于 expected 对象。

2) void 部分特化。表示一个 void 类型的预期值或在自身的存储中包含非预期值。如果包含非预期值,那么该值内嵌于 expected 对象。

如果程序以引用类型、函数类型,或 std::unexpected 的特化实例化 expected,那么程序非良构。另外,T 必须不是 std::in_place_t 或 std::unexpect_t。

模板形参

T-预期值的类型。类型必须是(可有 cv 限定的)void,或者符合可析构 (Destructible) 要求(尤其是不允许数组或引用类型)。
E-非预期值的类型。类型必须符合可析构 (Destructible) 要求,且必须对于 std::unexpected 为合法的模板实参(尤其是不允许数组、非对象类型及 cv 限定的类型)。

成员类型

成员类型定义
value_typeT
error_typeE
unexpected_typestd::unexpected<E>

成员别名模板

类型定义
rebind<U>std::expected<U, error_type>

数据成员

成员定义
bool has_valexpected 对象当前是否表示预期值
(仅用于阐述的成员对象*)
T val (仅限主模板)预期值
(仅用于阐述的变体成员对象*)
E unex非预期值
(仅用于阐述的变体成员对象*)

成员函数

(构造函数)

构造 expected 对象
(公开成员函数)

(析构函数)

销毁 expected 对象以及其所含的值
(公开成员函数)

operator=

赋值内容
(公开成员函数)
观察器

operator->operator*

访问预期值
(公开成员函数)

operator boolhas_value

检查对象是否含有预期值
(公开成员函数)

value

返回预期值
(公开成员函数)

error

返回非预期值
(公开成员函数)

value_or

如果有预期值则返回它,否则返回另一个值
(公开成员函数)

error_or

如果有非预期值则返回它,否则返回另一个值
(公开成员函数)
单子操作

and_then

若存在预期值则返回给定的函数在其上的结果,否则返回 expected 本身
(公开成员函数)

transform

若存在预期值则返回含有变换后的预期值的 expected,否则返回 expected 本身
(公开成员函数)

or_else

若 expected 含有预期值则返回其自身,否则返回给定的函数在非预期值上的结果
(公开成员函数)

transform_error

若含有预期值则返回 expected 本身,否则返回含有变换后非预期值的 expected
(公开成员函数)
修改器

emplace

原位构造预期值
(公开成员函数)

swap

交换内容
(公开成员函数)

非成员函数

operator==

(C++23)

比较 expected 对象
(函数模板)

swap(std::expected)

(C++23)

特化 std::swap 算法
(函数)

辅助类

unexpected

(C++23)

表示一个非预期值
(类模板)

bad_expected_access

(C++23)

指示对含有非预期值的 expected 的有检查访问的异常
(类模板)

unexpect_tunexpect

(C++23)

expected 中非预期值的原位构造标签
(类) (常量)

基本用法

1. 定义与初始化
#include <expected>
#include <string>// 定义一个可能返回 int 或字符串错误的 expected 类型
std::expected<int, std::string> parse_number(const std::string& input) {try {return std::stoi(input);} catch (...) {return std::unexpected("Invalid number format");}
}
2. 检查状态
auto result = parse_number("123");
if (result.has_value()) 
{std::cout << "Value: " << *result << std::endl;
} 
else 
{std::cout << "Error: " << result.error() << std::endl;
}
3. 访问值或错误
  • 直接访问

int value = result.value();      // 成功时返回值,失败时抛出 std::bad_expected_access
std::string err = result.error();// 失败时返回错误

安全访问

int value = result.value_or(0);  // 失败时返回默认值 0
4. transform:转换成功值
  • 功能:若 std::expected 包含成功值,则对其应用一个函数,返回新的 std::expected;若包含错误,则直接传递错误。
  • 适用场景:对成功值进行纯转换(不涉及可能失败的操作)。
示例:将整数结果转换为字符串
#include <expected>
#include <string>
#include <iostream>std::expected<int, std::string> computeValue(bool success) 
{if (success){return 42;}return std::unexpected("Error");
}int main() 
{auto result = computeValue(true).transform([](int x) { return "Answer: " + std::to_string(x*2); });if (result) {std::cout << *result << "\n"; // 输出: Answer: 42} else {std::cout << result.error() << "\n";}
}
5. and_then:链式执行可能失败的操作
  • 功能:若 std::expected 包含成功值,则对其应用一个返回新 std::expected返回值类型的函数;若包含错误,直接传递错误。
  • 适用场景:需要连续执行多个可能失败的操作(例如:先读取文件,再解析内容)。
示例:链式除法操作
#include <expected>
#include <string>
#include <iostream>std::expected<double, std::string> safeDivide(double a, double b) 
{if (b != 0){return a / b;}return std::unexpected("Division by zero");
}int main() 
{auto result = safeDivide(10, 2).and_then([](double x) { return safeDivide(x, 5); }) // 10/2=5 → 5/5=1.and_then([](double x) { return safeDivide(x, 0); }); // 1/0 → 错误if (result) {std::cout << *result << "\n";} else {std::cout << "Error: " << result.error() << "\n"; // 输出: Error: Division by zero}
}
6. or_else:处理错误
  • 功能:若 std::expected 包含错误,则对其应用一个处理函数(返回新 std::expected);若包含成功值,直接传递成功值。
  • 适用场景:错误恢复、日志记录或提供默认值。
示例:错误恢复和日志记录
#include <expected>
#include <string>
#include <iostream>std::expected<int, std::string> readConfig() {return std::unexpected("Config file missing");
}int main() {auto result = readConfig().or_else([](const auto& error) {std::cerr << "Log: " << error << "\n"; // 记录错误日志return std::expected<int, std::string>(100); // 提供默认值});std::cout << "Final value: " << *result << "\n"; // 输出: Final value: 100
}

一个简单的例子:

enum class Status : uint8_t
{Ok,connection_error,no_authority,format_error,
};bool connected() 
{return true;
}bool has_authority() 
{return false;
}bool format() 
{return false;
}std::expected<std::string, Status> read_data() 
{if (!connected())return std::unexpected<Status> { Status::connection_error };if (!has_authority())return std::unexpected<Status> { Status::no_authority };if (!format())return std::unexpected<Status> { Status::format_error };return {"my expected type"};
}int main() 
{auto result = read_data();if (result) {std::cout << result.value() << "\n";} else {std::cout << "error code: " << (int)result.error() << "\n";}
}

 这种方式无疑会简化错误处理的操作。

示例场景

1. 文件读取
#include <fstream>
#include <vector>std::expected<std::vector<char>, std::string> read_file(const std::string& path) 
{std::ifstream file(path, std::ios::binary);if (!file) {return std::unexpected("Failed to open file");}std::vector<char> data;file.seekg(0, std::ios::end);data.resize(file.tellg());file.seekg(0, std::ios::beg);file.read(data.data(), data.size());if (file.fail()) {return std::unexpected("Failed to read file");}return data;
}// 使用示例
auto data = read_file("config.txt");
if (data) 
{process_data(*data);
} 
else 
{log_error(data.error());
}
2. 数学计算
std::expected<double, std::string> safe_divide(double a, double b) 
{if (b == 0) {return std::unexpected("Division by zero");}return a / b;
}// 使用示例
auto result = safe_divide(10, 2);
if (result) 
{std::cout << "Result: " << *result << std::endl;
}

Monadic 操作(C++23)

std::expected 支持链式操作,类似函数式编程中的 map 和 and_then

#include <iostream>
#include <type_traits>
#include <utility> // for std::forward_like
#include <expected>std::expected<int, std::string> validate(int x) {if (x < 0) return std::unexpected("Negative value");return x;
}std::expected<int, std::string> process(int x) {return x * 2;
}int main()
{// 链式调用auto result = validate(42).and_then(process)  // 仅在成功时调用 process.transform([](int x) { return x + 1; }); // 转换值if (result) {std::cout << "Final value: " << *result << std::endl; // 输出 85}
}

对比其他错误处理方式

方式优点缺点
异常自动传播错误性能开销,控制流不透明
错误码无性能开销易被忽略,类型不安全
std::expected显式错误,类型安全,性能高效需要手动处理错误状态

注意事项

  1. 错误类型:错误类型可以是任意类型(如 std::error_code、自定义枚举或字符串)。

  2. 性能std::expected 无动态内存分配,适合性能敏感场景。

  3. 与异常结合:可以包装可能抛出异常的操作(如示例中的 parse_number)。

  4. 编译器支持:需要支持 C++23 的编译器(如 GCC 13、Clang 16+)。


总结

std::expected 提供了一种类型安全、显式的错误处理机制,适用于替代传统错误码或异常的场景。它通过模板参数明确区分成功值和错误类型,结合 Monadic 操作可以编写更清晰的链式逻辑。对于需要高性能和可预测性的代码(如库开发或嵌入式系统),std::expected 是一个强大的工具。

http://www.dtcms.com/a/456468.html

相关文章:

  • dw旅游网站模板下载邢台做网站推广的公司是哪家?
  • 电子贺卡在线制作网站西宁网站建设维护
  • 医院 网站建设中建八局招聘出国劳务
  • 美妆网站怎么做wordpress评论添加验证码
  • 怎样做直播网站app企业网络方案设计思路
  • 河南做外贸网站的公司简介域名转移 网站访问
  • 房地产建设网站erp软件是什么意思
  • 太原那有网站设计公司免费php源码资源网
  • html电影网站模板网站建设与网页制作教程
  • 找个网站wordpress主题背景插件
  • asp个人网站怎么建设徐州企业建站
  • 无锡网站优化方案营销网站模板html
  • 网站到底怎么做出来的营销型网站制作的方法
  • 网站模网站建设和维护面试题
  • 做全国社保代理的网站如何获取网站的seo
  • 北京网站建设服务中心赣州信息港网
  • 哪个网站做ppt模板赚钱徐州网架公司十大排名
  • 做网站的害处项目管理的软件有哪些
  • 做书评的网站有哪些黑马程序员培训费用
  • 网站建设完成推广微信开发者平台小程序
  • 深圳网站seo优化排名公司wordpress设置目录
  • 做网站的设计文档怎么做福田企业建站推广服务公司
  • 无锡市建设银行总行网站巴中微信开发 做网站
  • 余姚网站建设找哪家建筑网站资料排行榜
  • wordpress 多站点 用户猪八戒网网站建设
  • 黄石网站建设多少钱seo推广计划类型可以分为什么
  • 模版网站建设企业本地房产交易信息网
  • 小挑可以做网站吗电商网站的模式
  • 烟台学校网站建设深圳网站建设学校
  • 网上书店网页设计实训报告江西seo推广方案