【C++】optional的使用(一)

news2024/12/28 3:47:12

这篇文章介绍下C++17引入的std::optional

为什么要有 optional

一般来说,如果想要一个函数返回“多个”值,C++程序员倾向于使用结构体/类完成这个操作。即定义一个通用的结构体,在函数内部完成装填,然后返回一个实例化的结构体。

#include <iostream>

using namespace std;

struct Out {
    string out1 { "" };
    string out2 { "" };
};

pair<bool, Out> func(const string& in) {
    Out o;
    if (in.size() == 0)
        return { false, o };
    o.out1 = "hello";
    o.out2 = "world";
    return { true, o };
}

int main() {
    if (auto [status, o] = func("hi"); status) {
        cout << o.out1 << endl;
        cout << o.out2 << endl;
    }
    return 0;
}

(代码来自 https://zhuanlan.zhihu.com/p/64985296)

C++17引入了std::optional,介绍如下:

The class template std::optional manages an optional contained value,
i.e. a value that may or may not be present. A common use case for
optional is the return value of a function that may fail. As opposed
to other approaches, such as std::pair<T,bool>, optional handles
expensive-to-construct objects well and is more readable, as the
intent is expressed explicitly. 类模板 std::optional
管理一个可选的容纳值,即可以存在也可以不存在的值。 一种常见的 optional 使用情况是一个可能失败的函数的返回值。与其他手段,如
std::pair<T,bool> 相比, optional 良好地处理构造开销高昂的对象,并更加可读,因为它显式表达意图。

换句话说,一个普通的变量,只有不同的值。而optional相当于在外面套了一层壳,先考虑存不存在值,再考虑值是多少。

使用

对于像我这样的菜鸟来说,optional 的源代码十分复杂的。但是使用起来并不困难,理解上面的含义就行。

  /**
    * @brief Class template for optional values.
    */
  template<typename _Tp>
    class optional
    : private _Optional_base<_Tp>,
      private _Enable_copy_move<
	// Copy constructor.
	is_copy_constructible_v<_Tp>,
	// Copy assignment.
	__and_v<is_copy_constructible<_Tp>, is_copy_assignable<_Tp>>,
	// Move constructor.
	is_move_constructible_v<_Tp>,
	// Move assignment.
	__and_v<is_move_constructible<_Tp>, is_move_assignable<_Tp>>,
	// Unique tag type.

可以看到,本质上其实是个模板类,将包裹的类型以模板参数T的方式传入。

初始化

optional几种初始化如下:

    //初始化为空
    optional<int> int_empty;
    //使用有效值初始化(C++其他初始化方法也同样可用)
    optional<int> my_int = 2;
    //使用make_optional
    auto doubleOpt = std::make_optional(10.0);
    auto complexOpt = std::make_optional<std::complex<double>>(3.0, 4.0);
    //使用in_place
    optional<vector<int>> vectorOpt{in_place, {1, 2, 3}};
    //使用其它optional对象复制/移动构造
    auto optCopied = vectorOpt;

说一下第三点和第四点,就是这个std::make_optionalstd::in_place。我搜到的资料显示这代表直接调用模板T的构造函数,即“完美转发”。

假设我有这么一个类 TestOp:

struct TestOp
{
    TestOp() : age(100) {}
    int getAge() { return age; }

private:
    int age;
};

它有一个无参数的构造函数,但这个构造函数为成员赋默认值。这时,若使用如下写法

    optional<TestOp> test_op;
    cout << test_op.value().getAge() << endl;

会编译失败。因为optional并不会调用TestOp的默认构造函数,只会创建一个空的TestOp对象。
编译失败
这让我非常不理解,因为就算是未传入参数,应该调用T的默认构造函数才对。
你可能想到,如果初始化时直接传入构造函数呢?

    optional<TestOp> test_op{TestOp()};

这样写当然没问题,我们将得到包含默认TestOp对象的optional对象。但是在上面的代码中,将先构造出一个TestOp的临时对象,然后调用move函数将这个临时对象“移动”到optional存储的对象中,带来了额外的开销。在这种情况下,我们就只能使用std::in_place/ std::make_optional来“原地”构造optional底层存储的对象。

另一种情况是,TestOp禁用了移动构造和复制构造函数,这时候也只能用std::in_place/ std::make_optional

最后一种必须使用std::in_place/ std::make_optional的情况是,当你需要使用多个参数初始化同一个变量时,比如std::vector。没错,原生的 optional构造函数,并不支持多参数,神奇吧?
6
我猜想多参数的支持会导致歧义。

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

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

相关文章

Python项目——贪吃蛇

1、原理 整个界面由一个二维数组组成。游戏开始时&#xff0c;会随机生成一个苹果&#xff08;红点&#xff09;和一条蛇&#xff08;黄点&#xff09;。蛇会在二维数组中移动&#xff0c;当蛇碰到苹果时&#xff0c;苹果被吃&#xff0c;蛇的长度加一&#xff08;红点变黄点&…

【数据结构】八大排序之直接插入排序算法

&#x1f984;个人主页:修修修也 &#x1f38f;所属专栏:数据结构 ⚙️操作环境:Visual Studio 2022 一.直接插入排序简介及思路 直接插入排序(Straight Insertion Sort)是一种简单直观的插入排序算法. 它的基本操作是: 将一个数据插入到已经排好的有序表中,从而得到一个新的,数…

探索Nginx的奥秘--从代理到负载均衡的艺术实践

文章目录 &#x1f33a;Nginx的引入&#x1f33a;&#x1f33a;深刻理解正向代理与反向代理&#x1f33a;&#x1f339;Reverse proxy&#x1f339;&#x1f339;正向代理与反向代理的区别&#x1f339;&#x1f339;反向代理为什么叫反向代理&#x1f339;&#x1f339;负载均…

【DataSophon】大数据服务组件之Flink升级

&#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341;&#x1fa81;&#x1f341; &#x1fa81;&#x1f341;&#x1fa81;&am…

Logstash访问安全访问Elasticsearch集群

生成logstash证书: opensal pkcs12 -in elastic-stack-ca.p12 -clcerts -nokeys > logafash.cer openssl x509 -in logstash.cer -out logstash.pem 编排配置文件

移动端Vant中的Calendar日历增加显示农历(节日、节气)功能

核心&#xff1a; 使用 js-calendar-converter 库实现 npm地址&#xff1a;js-calendar-converter 内部使用原生calendar.js&#xff0c; 中国农历&#xff08;阴阳历&#xff09;和西元阳历即公历互转JavaScript库&#xff0c;具体实现感兴趣的可自行查看其实现源码。 原日…

NAS搭建WebDAV服务同步Zotero科研文献

文章目录 一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 Zotero 是一款全能型 文献管理器,可以 存储、管理和引用文献&#xff0c;不但免费&#xff0c;功能还很强大实用。 ​ Zotero 支…

c# bitmap压缩导致png不透明的问题解决

新建.net 6控制台项目 安装System.Drawing.Common包 代码如下 using System.Drawing; using System.Drawing.Imaging;namespace PngCompress02 {internal class Program{static void Main(string[] args){CompressPngImage("E:\Desktop\6.png", "E:\Desktop\6…

MySQL undo日志精讲

事务回滚的需求 我们说过事务需要保证原子性&#xff0c;也就是事务中的操作要么全部完成&#xff0c;要么什么也不做。但是偏偏有时候事务执行到一半会出现一些情况&#xff0c;比如&#xff1a; 情况一&#xff1a;事务执行过程中可能遇到各种错误&#xff0c;比如服务器本身…

基于ssm的简单学校课程管理系统的设计与实现(源码+调试)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于ssm的简单学校课程管…

智慧路灯杆如何实现雪天道路安全监测

随着北方区域连续发生暴雪、寒潮、大风等气象变化&#xff0c;北方多地产生暴雪和低温雨雪冰冻灾害风险&#xff0c;冬季雨雪天气深度影响人们出行生活&#xff0c;也持续增加道路交通风险。 智慧路灯杆是现代城市不可或缺的智能基础设施&#xff0c;凭借搭载智慧照明、环境监测…

读论文:Restormer: Efficient Transformer for High-Resolution Image Restoration

《Restormer: Efficient Transformer for High-Resolution Image Restoration》发表于2022年的CVPR&#xff0c;在 Transformer block 中进行了几个关键设计以提出一种新的高效的视觉 Transformer&#xff0c;称为 Restormer&#xff0c;再一次刷新了视觉 transformer 在高分辨…

山西电力市场日前价格预测【2023-12-16】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-12-16&#xff09;山西电力市场全天平均日前电价为259.00元/MWh。其中&#xff0c;最高日前电价为333.74元/MWh&#xff0c;预计出现在18:00。最低日前电价为0.00元/MWh&#xff0c;预计出…

Intellij IDEA 运行maven报错误“CreateProcess error=2, 系统找不到指定的文件“的完美解决方案

一、问题背景 博主正常使用着Intellij IDEA&#xff0c;不知道为什么突然Intellij IDEA报错&#xff0c;错误提示如下&#xff1a; Error:Cannot run program "C:\Program Files\Java\jdk1.8.0_351" 观察Intellij IDEA报错的原因&#xff0c;我们可以知道&#xff1…

​FL Studio2024最新版本好不好用?有哪些新功能

FL Studio2024版是一款在国内非常受欢迎的多功能音频处理软件&#xff0c;我们可以通过这款软件来对多种不同格式的音频文件来进行编辑处理。而且FL Studio 2024版还为用户们准备了超多的音乐乐器伴奏&#xff0c;我们可以直接一键调取自己需要的音调。 FL Studio 2024版不仅拥…

一分钟解决:vscode卡在“设置SSH主机:VS Code-正在本地下载 VS Code 服务器”

问题&#xff1a;vscode之前可正常使用&#xff0c;更新之后&#xff0c;连接服务器卡住了。 解决&#xff1a;从CMD或者你的终端连接服务器&#xff0c;进入vscode-server目录下&#xff0c;删除一些文件夹就行&#xff0c;然后使用vscode重新链接&#xff0c;它会自动下载新…

机器学习:自督导式学习模型

outline 自督导式模型有跨语言的能力 中文&#xff1a;DRCD的数据集英文&#xff1a;SQuAD的数据集 在104种语言上进行学习&#xff0c;并在英文上进行微调&#xff0c;结果在中文上效果也比较好。 XTREME Benchmark 只用英文进行微调&#xff0c;在其他剩下的语言中进行测试。…

【计算机视觉】SIFT

在边缘提取的时候&#xff0c;用高斯一阶导对信号进行卷积&#xff0c;响应值最大的就是边界如果用高斯二阶导对信号进行卷积&#xff0c;0点就是边界点&#xff08;二阶导等于0的点&#xff0c;对应一阶导的极值点&#xff09; 如果用高斯二阶导在不同的信号上进行卷积&#x…

基于主动安全的AIGC数据安全建设

面对AIGC带来的数据安全新问题&#xff0c;是不是就应该一刀切禁止AIGC的研究利用呢&#xff1f;答案是否定的。要发展AIGC&#xff0c;也要主动积极地对AIGC的数据安全进行建设。让AIGC更加安全、可靠的为用户服务。为达到此目的&#xff0c;应该从三个方面来开展AIGC的数据安…