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. ClickHouse的向量处理能力

    ClickHouse的向量处理能力 引言 在过去,非结构化数据(如文本.图片.音频.视频)通常被认为难以在数据库中直接使用,因为这些数据类型的多样性和复杂性.然而,随着技术的发展,嵌入技术可以将非结构 ...

  2. BI 工具如何助力市政设计公司实现数字化转型?

    一.前言 近年来,国家出台多个政策文件来鼓励和发展数字化和智能化,如<十四五规划>提出要推进产业数字化转型.<交通强国建设纲要>提出要大力发展智慧交通.上海市发布的<关于 ...

  3. 【SVN】属性功能配置

    一.配置SVN提交模板 更改SVN提交信息模板 (参考源博客): https://www.cnblogs.com/fairylyl/p/10505833.html 右键属性配置: 新建一项属性,选择[ ...

  4. 【Layui】15 日期时间选择器 Laydate

    文档地址: https://www.layui.com/demo/laydate.html [基本案例] 基本日期与国际日期 <fieldset class="layui-elem-f ...

  5. 从.net开发做到云原生运维(三)——.net core的学习路线

    1. 前言 前面几篇文章主要讲了.net技术相关的基本概念和一些涉及的项目什么,本身也没讲太多底层的技术,这篇文章依旧不讲具体的技术,主要介绍.net技术的学习路线.学习路线也是我18年毕业的时候看到 ...

  6. 【转载】 HTTP中的响应协议及302、304的含义

    原文地址: https://www.cnblogs.com/chenyablog/p/9197305.html ============================== 响应协议 HTTP/1.1 ...

  7. 简化数据流:Apache SeaTunnel实现多表同步的高效指南

    Apache SeaTunnel除了单表之间的数据同步之外,也支持单表同步到多表,多表同步到单表,以及多表同步到多表,下面简单举例说明如何实现这些功能. 单表 to 单表 一个source,一个sin ...

  8. SeaTunnel 发布成为 Apache 顶级项目后首个版本 2.3.2,进一步提高 Zeta 引擎稳定性和易用性

    近日,Apache SeaTunnel 正式发布 2.3.2 版本.此时距离上一版本 2.3.1 发布已有两个多月,期间我们收集并根据用户和开发者的反馈,在 2.3.2 版本中对 SeaTunnel ...

  9. 我们常用的地铁卡/银行卡,竟然运行着一个 Java 虚拟机

    我们日常使用 NFC 卡可以用来刷地铁,进出门禁,但是你有没有想过, 当我们使用一个 NFC 的 IC 卡刷卡进入地铁的时候,此时系统是如何知道我这个卡上有多少充值余额的? 这个薄薄的 NFC 卡到底 ...

  10. 神经网络之卷积篇:详解卷积步长(Strided convolutions)

    详解卷积步长 卷积中的步幅是另一个构建卷积神经网络的基本操作,让向展示一个例子. 如果想用3×3的过滤器卷积这个7×7的图像,和之前不同的是,把步幅设置成了2.还和之前一样取左上方的3×3区域的元素的 ...