std::optional 是 C++17 中引入的一个模板类,用于表示一个值可能存在也可能不存在的情况。

它可以存储一个值,或者表示没有值的状态,类似于其他编程语言中的“可选”类型。

std::optional主要特性:

  1. 值的存在性:可以使用 has_value() 方法检查 std::optional 是否包含一个有效的值。
  2. 访问值:可以使用 value() 方法获取存储的值,如果没有值,则会抛出 std::bad_optional_access 异常。还有 value_or(T&& default_value) 方法,可以在没有值的情况下返回一个默认值。
  3. 初始化:可以通过直接赋值、使用构造函数或 std::nullopt 来初始化。
  4. 赋值和重置:可以通过赋值来更新值,也可以使用 reset() 方法清除存储的值。

示例代码:

#include <iostream>
#include <optional> std::optional<int> findValue(bool found) {
if (found) {
return 42; // 返回一个值
}
return std::nullopt; // 返回无值状态
} int main() {
std::optional<int> opt = findValue(true); if (opt.has_value()) {
std::cout << "Value: " << opt.value() << std::endl;
} else {
std::cout << "No value found." << std::endl;
} return 0;
}

在这个示例中,findValue 函数返回一个 std::optional<int>,可以根据条件返回一个整数值或无值状态。这种特性使得处理可能缺失的值更加安全和直观。

std::nullopt

当使用 std::optional 作为函数的返回值时,通常用 std::nullopt 来表示无值状态。这使得函数可以明确地指示操作是否成功以及返回的值是否有效。

示例

以下是一个简单的示例,演示如何使用 std::optional 作为函数返回值:

#include <iostream>
#include <optional>
#include <string> std::optional<std::string> findUserById(int id) {
// 假设我们在一个用户数据库中查找
if (id == 1) {
return "Alice"; // 找到用户,返回姓名
} else {
return std::nullopt; // 未找到用户,返回无值
}
} int main() {
auto user1 = findUserById(1);
if (user1) {
std::cout << "Found user: " << *user1 << std::endl;
} else {
std::cout << "User not found." << std::endl;
} auto user2 = findUserById(2);
if (user2) {
std::cout << "Found user: " << *user2 << std::endl;
} else {
std::cout << "User not found." << std::endl;
} return 0;
}

关键点

  1. 返回 std::nullopt:如果函数无法返回有效值,使用 return std::nullopt; 来表示无值状态。

  2. 检查返回值:在调用函数后,使用布尔上下文(如 if (user1))检查返回的 std::optional 是否有值。

  3. 解引用值:只有在确认有值后,才可以安全地解引用 std::optional 的值。

这种方法使得函数可以清晰地表明其执行结果,避免使用特殊值(如 nullptr-1)来表示错误状态,从而提高了代码的可读性和安全性。

{}

在 C++ 中,使用 {} 可以表示无值,但其效果和意图可能不够明确,具体取决于上下文。

对于 std::optional

对于 std::optional,可以使用 {} 来表示无值状态,通常这是有效的,因为 {} 会调用 std::optional 的默认构造函数:

#include <optional>

std::optional<int> opt = {}; // 表示无值

对于 std::variant

对于 std::variant,使用 {} 也是可以的,通常会导致它被初始化为第一个类型(假设你没有定义其他构造),或者被视为 std::monostate(如果它是第一个选项)。

例如:

#include <variant>

using Result = std::variant<std::monostate, int>;

Result result = {}; // 被视为 std::monostate

注意事项

  1. 可读性:虽然可以使用 {} 表示无值,但这可能会降低代码的可读性。在某些情况下,显式使用 std::nullopt(对于 std::optional)或 std::monostate{}(对于 std::variant)会更加清晰。

  2. 类型安全:确保你清楚 {} 在具体上下文中的含义,避免可能的混淆。例如,在 std::variant 中,{} 可能被解释为选择第一个类型。

综上所述,虽然可以使用 {} 来表示无值,但推荐在合适的场景中使用更明确的语义以提高代码的可读性和可维护性。

`std::optional` 函数返回值的更多相关文章

  1. string类find函数返回值判定

     string类find函数返回值判定 代码示例 #include<iostream> #include<cstring> using namespace std; int m ...

  2. C++ const修饰函数、函数参数、函数返回值

    const修饰函数 在类中将成员函数修饰为const表明在该函数体内,不能修改对象的数据成员而且不能调用非const函数.为什么不能调用非const函数?因为非const函数可能修改数据成员,cons ...

  3. C++函数返回值发生的对象复制

    最近用QT做一个监控系统的项目,需要显示目标的运动轨迹,每次目标移动后,就在目标的轨迹中(用vector记录)添加一条新轨迹. 但是在运行中画面里一直不出现轨迹,经过调试发现是记录轨迹的函数出错了. ...

  4. 获得函数返回值类型、参数tuple、成员函数指针中的对象类型

    //function_traits.h,获得函数返回值类型.参数tuple.成员函数指针中的对象类型 //参考https://github.com/qicosmos/cosmos/blob/maste ...

  5. 【C/C++】引用&的含义/语法/作为函数参数/函数返回值/本质/常量引用

    含义 引用不产生副本,只是给原变量起了别名. 对引用变量的操作就是对原变量的操作. 基本语法 数据类型 &别名 = 原名 e.g. int a = 10; int &b = a; // ...

  6. pytho获取C函数返回值

    python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...

  7. shell调用函数返回值深入分析

    编写shell脚本过程中,我们经常会自定义一些函数,并根据函数的返回值不同来执行相应的流程,那么我们如何来获取函数的返回值呢? 首先shell中调用函数有两种方式: 第一种:value=`functi ...

  8. Python从线程获取函数返回值

    Python中利用强大的threading模块可以很容易的实现多线程开发,提高运行速度.这一般是对某个进行大量计算操作的的函数进行多线程处理,然后合并各线程的结果.获取函数返回值的方法可以如下: 1) ...

  9. 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数

    [源码下载] 速战速决 (3) - PHP: 函数基础, 函数参数, 函数返回值, 可变函数, 匿名函数, 闭包函数, 回调函数 作者:webabcd 介绍速战速决 之 PHP 函数基础 函数参数 函 ...

  10. c语言main函数返回值、参数详解(返回值是必须的,0表示正常退出)

    C语言Main函数返回值 main函数的返回值,用于说明程序的退出状态.如果返回0,则代表程序正常退出:返回其它数字的含义则由系统决定.通常,返回非零代表程序异常退出. 很多人甚至市面上的一些书籍,都 ...

随机推荐

  1. 【Java】EasyCaptcha 封装验证码接口

    依赖坐标: <dependency> <groupId>com.github.whvcse</groupId> <artifactId>easy-cap ...

  2. 【Java】自制查找工具

    需求:查找后台代码中写的SQL是否包含拆分表,如果存在,则返回那些表名 Context.txt 粘贴我们找到的DAO层代码,因为所有方法封装的SQL都在DAO层里[就理解为筛查的字符串] Dictio ...

  3. 【Vue】13 VueRouter Part3 路由守卫

    单页应用中,只存在一个HTML文件,网页的标签,是通过title标签显示的,我们在单页应用中如何修改? JS操作: window.document.title = "标签名称" 也 ...

  4. 【转载】python画带方差的折线图(csdn上最简洁的代码之一附上)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 原文链接:https://blog.csdn.net/a1920993165/article/ ...

  5. 目前AI模型与CAE(计算机辅助工程)结合所能达到的技术水平?

    相关: https://www.anscos.com/odyssee.html ODYSSEE CAE只需进行几次先前的CAE模拟,即可实时预测.优化并可靠地生成准确的结果.ODYSSEE CAE以非 ...

  6. 预处理共轭梯度算法(Preconditioned Conjugate Gradients Method)的代码实现

    前文: 预处理共轭梯度算法(Preconditioned Conjugate Gradients Method) 给出代码: import numpy as np # from rllab.misc. ...

  7. Ubuntu18.04 环境下 解决VScode中空格长度减小的问题

       问题:   Ubuntu下安装vscode后发现空格特别小,只有正常空格的一半大小 ======================================================= ...

  8. 传奇人物:“Linux之父”林纳斯·托瓦兹(Linus Torvalds)

    偶然看到一个视频: https://www.youtube.com/watch?v=H32IXRkPjHA 林纳斯·托瓦兹(Linus Torvalds)是当之无愧的技术领袖.尤其是那句Just fo ...

  9. 如何更改Python项目中的 模块搜索第一路径

    内容承接上文: Python语言中当前工作目录(Current Working Directory, cwd)与模块搜索第一路径都是指什么??? 上文中已经解释了当前工作目录cwd与模块搜索路径的区别 ...

  10. python语言绘图:绘制一组以beta分布为先验,以二项分布为似然的贝叶斯后验分布图

    代码源自: https://github.com/PacktPublishing/Bayesian-Analysis-with-Python ============================= ...