C++17中std::optional的使用

      模版类std::optional管理一个可选的(optional)存储值(contained value),即可能存在也可能不存在的值。std::optional的一个常见用例是存储可能失败的函数的返回值。与其它方法相反(例如std::pair<T, bool>),std::optional可以很好地处理构造成本高昂的对象,并且更具可读性,因为意图被明确表达。
      在任何给定时间点的std::optional的任何实例要么存储值,要么不存储值。如果std::optional存储一个值,则保证该值作为std::optional对象占用空间的一部分进行分配,即不会发生动态内存分配。
      当std::optional<T>类型的对象根据上下文转换为bool时,如果该对象存储一个值,则转换返回true;如果不存储值,则转换返回false。
      和std::variant、std::any一样,std::optional对象有值语义,其拷贝操作会被实现为深拷贝。std::optional对象也支持move语义
      std::optional模拟了一个可以为空的任意类型的实例,它可以被用作成员、参数、返回值等。

      std::optional提供了一种标准化的方式来表示可选值(optional value),消除了对空指针的需要并增强了代码的可读性。std::optional是使用原始指针或其它机制来表示缺失值或可选值的更安全的替代方案。根据设计,std::optional强制用户在访问某个值之前显式检查该值是否存在,从而最大限度地降低空指针解引用错误的风险。

      std::make_optional:创建一个用参数初始化的std::optional对象。

      std::nullopt是std::nullopt_t类型的常量,用于指示具有未初始化(或空的)状态的std::optional类型,作为std::optional对象无值时候的"值".
      std::optional特别适合延迟初始化问题,它本身就是延迟初始化的一个实例。所存储的T可以在构造时初始化,或者稍后初始化,或者从不初始化。

int test_optional_init()
{std::optional<int> var;if (!var.has_value())std::cout << "var is not set\n"; // var is not setvar = 8; // error: *var = 8, 因为var采用默认初始化为空if (var.has_value())std::cout << "var is present: " << var.value() << "\n"; // var is present: 8if (var)std::cout << "var is present: " << *var << "\n"; // var is present: 8std::optional<int> var2{ std::nullopt }; // 将var2初始化置于"empty"状态if (!var2.has_value())std::cout << "var2 is not set\n"; // var2 is not setstd::optional<std::string> var3{ "China" };if (var3 > std::nullopt)std::cout << "var3 > std::nullopt\n"; // var3 > std::nulloptauto var4 = std::make_optional<std::vector<char*>>({ "China", "Beijing", "Haidian" });for (const auto& v : *var4)std::cout << " " << v; //  China Beijing Haidianstd::cout << "\n";// 内建类型可不需指明存储类型,deduction guidestd::optional var5{ 2 }; std::cout << "var5: " << var5.value() << "\n"; // var5: 2std::optional var6{ std::string{"China"} };std::cout << "var6: " << var6.value() << "\n"; // var6: Chinareturn 0;
}

      std::optional成员函数:
      1.访问存储值:
      (1).var.value():返回引用;如果没有值,会抛出std::bad_optional_access异常;
      (2).*var:如果没有值,会crash(or undefined behavior),返回存储值的引用;应该只用于已经确定含有值的场景
      (3).var.value_or:返回值,注意与value()的区别;如果没有值,则获取备选值;
      (4).var->:返回存储值的指针,可访问内部值的成员
      2.emplace:赋予一个新值(in-place);如果在调用之前已经存储一个值,则通过调用其析构函数来销毁所存储的值;
      3.reset:如果存储一个值,则销毁该值;否则,没有任何影响;
      4.has_value:返回std::optional对象是否存有值;
      5.operator bool():返回std::optional对象是否存有值;
      6.swap:交换两个std::optional对象的值;
      非成员函数:比较std::optional对象:operator==, !=, <, <=, >, >=, <=>。比较std::optional对象时,"empty"值即std::nullopt比任何有值的std::optional对象都要小
      std::bad_optional_access:是一个异常类,直接派生自std::exception,用于处理在访问std::optional对象时发生的错误,当尝试访问一个没有存储值的std::optional对象时,会抛出std::bad_optional_access异常。

int test_optional_member_functions()
{// 获取std::optional值: var.value(), *var, var.value_or, var->std::optional<int> var{ 8 };std::cout << "var: " << var.value() << ", " << *var << "\n"; // var: 8, 8*var = 6; std::cout << "var: " << *var << "\n"; // var: 6var = 8; std::cout << "var: " << *var << "\n"; // var: 8*var = 10; std::cout << "var: " << var.value_or(66) << "\n"; // var: 10var.reset(); std::cout << "var: " << var.value_or(66) << "\n"; // var: 66std::optional<std::string> var2{ "China" };std::cout << "var2: " << var2->data() << "\n"; // var2: Chinavar.reset(); // or: var = {};try {std::cout << "var: " << var.value() << "\n";//std::cout << "var: " << *var << "\n"; // 直接crash掉}catch (const std::bad_optional_access& e) {std::cout << "exception: " << e.what() << "\n"; // var: exception: Bad optional access}std::string str{ "Beijing" }; // 不要对常量变量使用std::movestd::optional<std::string> var3(std::move(str));std::cout << "var3: " << var3.value() << ", str: " << str << "\n"; // var3: Beijing, str:var3.emplace("Haidian");std::cout << "var3: " << var3.value() << "\n"; // var3: Haidianif (var3.has_value())std::cout << "var3 has value\n"; // var3 has valueif (var3)std::cout << "var3 has value\n"; // var3 has valuestd::cout << "var2: " << var2.value() << ", var3: " << var3.value() << "\n"; // var2: China, var3: Haidianvar2.swap(var3);std::cout << "var2: " << var2.value() << ", var3: " << var3.value() << "\n"; // var2: Haidian, var3: Chinaif (var2 != var3)std::cout << "var2 != var3\n"; // var2 != var3return 0;
}

      执行结果如下图所示:

      GitHub:https://github.com/fengbingchun/Messy_Test

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

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

相关文章

在GORM中使用并发

一个全面的指南&#xff0c;如何安全地使用GORM和Goroutines进行并发数据处理 效率是现代应用程序开发的基石&#xff0c;而并发在实现效率方面发挥着重要作用。GORM&#xff0c;这个强大的Go对象关系映射库&#xff0c;使开发人员能够通过Goroutines embrace并行性。在本指南…

Go,14周年[译]

国内的双十一购物狂欢已没有了当年的那种热闹与喧嚣&#xff0c;但大洋彼岸的Go团队却始终保持稳中有增的开发和语言演进节奏。今晨Go核心团队的Russ Cox[1]代表Go语言项目团队在Go官博上发表了《Fourteen Years of Go》[2]的博文&#xff0c;纪念Go语言开源14周年[3]&#xff…

【数据结构与算法】JavaScript实现单向链表

文章目录 一、单向链表简介二、封装单向链表类2.0.创建单向链表类2.1.append(element)2.2.toString()2.3.insert(position,element)2.4.get(position)2.5.indexOf(element)2.6.update(position,element)2.7.removeAt(position)2.8.其他方法2.9.完整实现 一、单向链表简介 链表…

Tomcat学习

一、入门 在webapp里面必须先创建一个文件夹&#xff0c;文件夹里面放的内容&#xff0c;才会被访问到。 创建一个javaweb项目后 二、servlet 1.概述 2.servlet生命周期 3.servlet实例的创建时机 4.Servlet实例的初始化参数 5.HTTP状态码 6.servelet返回JSON数据 7.fa Servel…

C语言——个位数为 6 且能被 3 整除但不能被 5 整除的三位自然数共有多少个,分别是哪些?

#define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int i,j0;for(i100;i<1000;i) {if(i%106&&i%30&&i%5!0){printf("%6d",i); j;}}printf("\n一共%d个\n",j);return 0; } %6d起到美化输出格式的作用&#xff…

C语言基础篇4:变量与存储

1 局部变量和全局变量 在介绍局部变量和全局变量前&#xff0c;先了解一些关于作用域方面的内容。作用域的作用就是决定程序中的哪些语句是可用的&#xff0c;换句话说&#xff0c;就是程序中的可见性。作用域有局部作用域和全局作用域&#xff0c;那么局部变量就具有局部作用域…

代码随想录算法训练营第四十九天丨 动态规划part12

309.最佳买卖股票时机含冷冻期 思路 相对于动态规划&#xff1a;122.买卖股票的最佳时机II (opens new window)&#xff0c;本题加上了一个冷冻期 在动态规划&#xff1a;122.买卖股票的最佳时机II (opens new window)中有两个状态&#xff0c;持有股票后的最多现金&#xf…

NSS [HUBUCTF 2022 新生赛]checkin

NSS [HUBUCTF 2022 新生赛]checkin 判断条件是if ($data_unserialize[username]$username&&$data_unserialize[password]$password)&#xff0c;满足则给我们flag。正常思路来说&#xff0c;我们要使序列化传入的username和password等于代码中的两个同名变量&#xff0…

番外 1 : Java 环境下的 selenium 搭建

Java 环境下的 selenium 搭建 一 . 下载谷歌浏览器二 . 下载谷歌浏览器驱动2.1 查看谷歌浏览器版本2.2 下载对应版本的谷歌驱动2.3 解压下载好的驱动压缩包 , 将下载好的 chromedriver.exe 放到java 系统环境变量下 三 . 下载 Edge 浏览器的驱动3.1 查看 Edge 浏览器的版本3.2 …

k8s的Init Containers容器实现代码版本升级发布和deployment版本回退:实战操作版

Pod中的初始化容器&#xff1a;Init Containers initContainers实现理论前提:同一个Pod内的容器共享 网络、volume等资源 Init Containers 在Kubernetes中&#xff0c;init容器是在同一个Pod中的其他容器之前启动和执行的容器。它的目的是为Pod上托管的主应用程序执行初始化…

洛谷P9388 [THUPC 2023 决赛] 先人类的人类选别(主席树+权值线段树)

题目 思路来源 P9388 [THUPC 2023 决赛] 先人类的人类选别 - 违规用户名FkZyA0!2 的博客 - 洛谷博客 题解 这个题是2023ccpc深圳热身赛的题目&#xff0c;也是thupc2023决赛的题目&#xff0c; 学弟问了一下&#xff0c;于是就乱搞了一下&#xff0c;搞了很久才a&#xff0…

Linux ____03、文件类型、属性、修改文件属性(更改文件权限)(命令)

文件类型、属性、修改文件属性 一、文件类型二、文件属性三、修改文件属性1、chgrp&#xff1a;更改文件属组2、chown&#xff1a;更改文件属主&#xff0c;也可以同时更改文件属组3、chmod&#xff1a;更改文件9个属性————————如觉不错&#xff0c;随手点赞&#xff…

微信小程序真机调试连接状态一直在正常和未链接之间反复横跳?

背景&#xff1a;小程序真机调试的时候&#xff0c;发现真机的network不显示接口调用情况&#xff0c;控制台也没有输出内容。具体如下所示&#xff1b; 解决方法&#xff1a; 1、确保手机端连接的网络和微信开发者工具网络一致&#xff0c;比如用同一个WiFi 2、真机自动调试…

编程知识\_C与汇编深入分析

1. 汇编怎么调用C函数 1.1 直接调用 bl main 1.2 想传参数怎么办&#xff1f; 在arm中有个ATPCS规则(ARM-THUMB procedure call standard&#xff08;ARM-Thumb过程调用标准&#xff09;。 约定r0-r15寄存器的用途&#xff1a; r0-r3 调用者和被调用者之间传参数 r4-r11 函…

Flink SQL自定义标量函数(Scalar Function)

使用场景&#xff1a; 标量函数即 UDF&#xff0c;⽤于进⼀条数据出⼀条数据的场景。 开发流程&#xff1a; 实现 org.apache.flink.table.functions.ScalarFunction 接⼝实现⼀个或者多个⾃定义的 eval 函数&#xff0c;名称必须叫做 eval&#xff0c;eval ⽅法签名必须是 p…

冒泡排序

贵阳这个地方的天气变化好大呀&#xff0c;前两天晒大太阳&#xff0c;今天就冷的脚抖&#xff0c;简直不要太冷&#xff0c;但是不管怎么样&#xff0c;还是要学习的哟&#xff01; 冬天来了&#xff0c;春天确实还有一点远&#xff01; 好了&#xff0c;话不多说&#xff0c;…

springboot rocketmq 延时消息、延迟消息

rocketmq也有延迟消息&#xff0c;经典的应用场景&#xff1a;订单30分钟未支付&#xff0c;则取消的场景 其他博客提到从rocketmq5.0开始&#xff0c;支持自定义延迟时间&#xff0c;4.x只支持预定义延迟时间&#xff0c;安装rocketmq可参考RocketMq简介及安装、docker安装ro…

【C++】模板初阶

目录 一&#xff0c;泛型编程 二&#xff0c;函数模板 1&#xff0c;函数模板概念 2&#xff0c;函数模板格式 3&#xff0c;函数模板的原理 4&#xff0c;函数模板的实例化 5&#xff0c;模板参数的匹配原则 三&#xff0c;类模板 1&#xff0c;类模板的定义格式 2&…

⑤ 【MySQL】DCL语句 —— 用户管理、权限控制

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL用户与权限 ⑤ 【MySQL】DCL语句 —— 用…

pytorch中对nn.BatchNorm2d()函数的理解

pytorch中对BatchNorm2d函数的理解 简介计算3. Pytorch的nn.BatchNorm2d()函数4 代码示例 简介 机器学习中&#xff0c;进行模型训练之前&#xff0c;需对数据做归一化处理&#xff0c;使其分布一致。在深度神经网络训练过程中&#xff0c;通常一次训练是一个batch&#xff0c…