【cpp】std::optional

原文地址

Intro

float divide(float a, float b)
{if (b == 0){return ?;}return a / b;
}

这里以一个除法函数为例,当 b 为 0 的时候,明显是除法的异常,但是怎样把这个状态返回给调用方呢?

常见的方法有如下几种

  • 抛异常,当除0时抛出相关的异常,调用方捕获异常
  • 返回一个特殊的值 (-1, infinity, nullptr) 这种需要和调用方约定好,语义不是很清晰。
  • Optional types. 这是一种类型安全并且表达力更强。

std::optional 在 c++17中被加入,以前的c++标准可以通过 boost::optional 来获取。在c++17中可以使用#include <optional> 来使用这个类型。

经过 std::optional 封装的仍然是一个值类型,可以拷贝。 std::optional不需要在堆上申请内存。

When to use

通常,可能在这些场景使用 std::optional封装

  • 需要较好的表示空类型 (nullable type)
    • 替代使用特殊值 (-1, nullptr, NO_VALUE 或者其他)
    • 比如某些值可能存在可能不存在,但是我们又需要知道是否存在, 比如,在统计年龄的时候,可能有的数据里面没有年龄,这个时候我们可以使用std::optional<int>表示。
  • 返回一个执行失败的结果
    • 比如除0 错误,不能得到正确的值的时候。
  • 懒加载资源的时候
    • 比如,一个 resource 类型没有默认的构造函数,但是构造的工作 比较庞大,可以使用 std::optional<Resource>来定义,然后在需要的时候来加载。
    • 在传参的时候

Basic Example

std::optional<std::string> UI::FindUserNick()
{if (nick_available)return { mStrNickName };return std::nullopt; // same as return { };
}// use:
std::optional<std::string> UserNick = UI->FindUserNick();
if (UserNick)Show(*UserNick);

Creation

// empty:
std::optional<int> oEmpty;
std::optional<float> oFloat = std::nullopt;// direct:
std::optional<int> oInt(10);
std::optional oIntDeduced(10); // deduction guides// make_optional
auto oDouble = std::make_optional(3.0);
auto oComplex = make_optional<std::complex<double>>(3.0, 4.0);// in_place
std::optional<std::complex<double>> o7{std::in_place, 3.0, 4.0};// will call vector with direct init of {1, 2, 3}
std::optional<std::vector<int>> oVec(std::in_place, {1, 2, 3});// copy/assign:
auto oIntCopy = oInt;

获取值

// by operator*
std::optional<int> oint = 10;
std::cout<< "oint " << *opt1 << '\n';// by value()
std::optional<std::string> ostr("hello");
try
{std::cout << "ostr " << ostr.value() << '\n';  
}
catch (const std::bad_optional_access& e)
{std::cout << e.what() << "\n";
}// by value_or()
std::optional<double> odouble; // empty
std::cout<< "odouble " << odouble.value_or(10.0) << '\n';

一种稳妥的做法时在访问的时候判断是否为空

    // compute string function:std::optional<std::string> maybe_create_hello();  // ...  if (auto ostr = maybe_create_hello(); ostr)std::cout << "ostr " << *ostr << '\n';  else  std::cout << "ostr is null\n";

修改值

#include <optional>
#include <iostream>
#include <string>class UserName
{
public:explicit UserName(const std::string& str) : mName(str){ std::cout << "UserName::UserName(\'";std::cout << mName << "\')\n"; }~UserName() {std::cout << "UserName::~UserName(\'";std::cout << mName << "\')\n"; }private:std::string mName;
};int main()
{std::optional<UserName> oEmpty;// emplace:oEmpty.emplace("Steve");// calls ~Steve and creates new Mark:oEmpty.emplace("Mark");// reset so it's empty againoEmpty.reset(); // calls ~Mark// same as://oEmpty = std::nullopt;// assign a new value:oEmpty.emplace("Fred");oEmpty = UserName("Joe"); 
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/82013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络安全深入学习第六课——热门框架漏洞(RCE— Weblogic反序列化漏洞)

文章目录 一、Weblogic介绍二、Weblogic反序列化漏洞历史三、Weblogic框架特征1、404界面2、登录界面 四、weblogic常用弱口令账号密码五、Weblogic漏洞介绍六、Weblogic漏洞手工复现1、获取账号密码&#xff0c;这是一个任意文件读取的漏洞1&#xff09;读取SerializedSystemI…

MySQL性能优化——MYSQL执行流程

MySQL 执行流程1-5如下图。 MySQL 的架构共分为两层&#xff1a;Server 层和存储引擎层&#xff0c; Server 层负责建立连接、分析和执行 SQL。MySQL 大多数的核心功能模块都在这实现&#xff0c;主要包括连接器&#xff0c;查询缓存、解析器、预处理器、优化器、执行器等。…

【C刷题训练营】第四讲(打好基础很重要)

前言: 大家好&#xff0c;这是c语言刷题训练营的第四讲&#xff0c;打好基础便于对c语言语法与算法思维的提高&#xff0c;感谢你的来访与支持&#xff01; &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨刷题专栏…

操作系统基本概念

目录 一、基本概述 二、操作系统的特点 &#xff08;一&#xff09;并发性&#xff08;实质是微观的串行、宏观的并行&#xff09; 1. 对比看&#xff1a;并行性 2. 单核CPU和多核CPU &#xff08;二&#xff09;共享性 &#xff08;三&#xff09;虚拟性 &#xff08;…

BIO AIO NIO 的区别

BIO AIO NIO 是 Java 中用于 I/O 操作的三种不同的编程模型。它们的区别在于它们执行I/O 操作的方式和效率。在讲 BIO,NIO,AIO 之前先来回顾一下这样几个概念&#xff1a;同步与异步&#xff0c;阻塞与非阻塞。 同步与异步 同步&#xff1a;同步就是发起一个调用后&#xff…

LeetCode: 高频链表题目总结 - Python

LeetCode:高频链表题目总结 问题描述&#xff1a; LeetCode: 2. 两数相加 , 注意是逆序存储&#xff0c;相加求和LeetCode: 19. 删除链表的倒数第 N 个结点LeetCode: 21. 合并两个有序链表LeetCode: 23. 合并 K 个升序链表LeetCode: 24. 两两交换链表中的节点 &#xff0c;两…

升级OpenSSL并进行编译安装

Packaging (OpenSSL)组件存在安全漏洞的原因是由于当前爆出的Openssl漏洞。 这个漏洞可能会导致泄露隐私信息&#xff0c;并且涉及的机器和环境也有所不同&#xff0c;因此修复方案也会有所不同。 目前&#xff0c;一些服务器使用的Nginx是静态编译OpenSSL&#xff0c;直接将Op…

LeetCode-37-解数独

题目描述&#xff1a;编写一个程序&#xff0c;通过填充空格来解决数独问题。 数独的解法需 遵循如下规则&#xff1a; 数字 1-9 在每一行只能出现一次。 数字 1-9 在每一列只能出现一次。 数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例图&am…

2023陇剑杯

2023陇剑杯初赛WP HW hard_web_1 ​ 首先判断哪个是服务器地址 ​ 从响应包看&#xff0c;给客户端返回数据包的就是服务器 所以确定服务器地址是192.168.162.188​ 再从开放端口来看&#xff0c;长期开放的端口 客户端发送一个TCP SYN包&#xff08;同步请求&#xff…

记一次线上BUG排查过程

1. 线上遇到一个非常奇怪的bug&#xff0c;为一个用户分配业务线类型后&#xff0c;该用户登录时&#xff0c;提示502&#xff0c;但其它的用户登录完全是正常的 2. 问题现象 3. 排查思路 先去看线上日志&#xff0c;看是否有error&#xff0c;但日志里边这个接口200正常返回…

Django系列:Django的项目结构与配置解析

Django系列 Django的项目结构与配置解析 作者&#xff1a;李俊才 &#xff08;jcLee95&#xff09;&#xff1a;https://blog.csdn.net/qq_28550263 邮箱 &#xff1a;291148484163.com 本文地址&#xff1a;https://blog.csdn.net/qq_28550263/article/details/132893616 【介…

Nginx配置最佳实践

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

2023/9/18 -- C++/QT

作业 完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两…

【论文阅读 05】图像异常检测研究现状综述

1 图像异常检测任务 图像异常检测任务根据异常的形态可以分为定性异常的分类和定量异常的定位两个类别. 定性异常的分类&#xff1a;整体地给出是否异常的判断&#xff0c;无需准确定位异常的位置。 如图2左上图所示, 左侧代表正常图像, 右侧代表异常图像, 在第1行中,模…

企业电子招投标采购系统源码——功能模块功能描述+数字化采购管理 采购招投标

功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查看所…

docker run:--privileged=true选项解析(特权模式:赋予容器几乎与主机相同的权限)

文章目录 Docker的--privilegedtrue选项1. Docker 容器的安全性1.1 Linux Namespace 和 Capabilities1.2 限制和权限 2. Docker的--privilegedtrue选项2.1 --privilegedtrue的作用2.2 --privilegedtrue的风险 3. 结论 Docker的–privilegedtrue选项 Docker在创建和运行容器时&…

【在学】卡尔曼滤波/分布式卡尔曼滤波

在学&#xff0c;持续更新&#xff0c;欢迎交流… 想看看卡尔曼滤波/分布式卡尔曼滤波坑里还有多少人… 2023.08.18 为了令卡尔曼滤波器开始工作&#xff0c;我们需要告诉卡尔曼两个零时刻的初始值&#xff0c;是X(0|0)和P(0|0)。他们的值不用太在意&#xff0c;随便给一个就…

国家高新技术企业认定六个必要条件详细解读!

相信很多企业都想认定高新技术企业&#xff0c;因为认定成功的高新技术企业&#xff0c;可以享受很多政府资助政策&#xff0c;为公司创造很多便利条件。 但是&#xff0c;很多企业对于高企认定的条件却比较迷糊&#xff0c;今天至善科技为大家解读一下国家高新技术企业认定的六…

Maven 安装配置

Maven 安装配置 文章目录 Maven 安装配置一、下载 Maven二、解压Maven核心程序三、指定本地仓库四、配置阿里云镜像仓库4.1 将原有的例子配置注释掉4.2 加入新的配置 五、配置 Maven 工程的基础 JDK 版本六、配置环境变量6.1 检查 JAVAHOME 配置是否正确6.2 配置 MAVENHOME6.3 …

node 之 express 框架(初级)

一、express 热更新 1、安装扩展 npm install node-dev -D2、在根目录下的 package.json 文件中进行配置 3、之后的启动执行下面的命令即可 npm run dev二、mvc中的 模板引擎 1、ejs模板引擎的安装 npm install ejs -s2、在根目录下的app.js文件中配置 app.set(view engin…