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. js 做树形数组查询筛选功能

    对二级菜单进行搜索查询: watch: { librarySearch(val) { if(val == '') { this.libraryFiles = this.libraryFilesAll ...

  2. 使用 useRequestURL 组合函数访问请求URL

    title: 使用 useRequestURL 组合函数访问请求URL date: 2024/7/26 updated: 2024/7/26 author: cmdragon excerpt: 摘要: ...

  3. python_xecel

    移动并重命名工作簿 1 from pathlib import Path # 导入pathlib模块的path类 2 import time 3 4 # Press the green button ...

  4. Scratch植物大战僵尸全套素材包免费下载

    scratch植物大战僵尸全套素材包,包含227个丰富多样的素材,涵盖角色.背景.动态gif.为Scratch创作者提供丰富资源,助力创作精彩作品. 免费下载地址:www.xiaohujing.com ...

  5. docker 构建镜像拉取镜像生成实例

    实战tomcat镜像 准备镜像文件 编写dockerfile 首先将tomcat和jdk软件包上传 创建tomcat文件夹,将文件传送到tomcat文件夹 创建Dockerfile(不用加-f指定)文 ...

  6. IP地址的精细化操作(将IP地址转为相对应的地址)

    第一步: 导入maven依赖: <dependency> <groupId>org.lionsoul</groupId> <artifactId>ip2 ...

  7. 【Java】暂存逻辑

    需求说明: 需求是填写一个表单时暂时保存输入项,不提交表单 回来再次填写时可以恢复或者放弃,或者更改内容继续暂存 放两张UI图,一个移动端,一个手机端: 逻辑分析: 存储方式有这么几种,Cookie存 ...

  8. 【Windows】开放共享目录

    在项目里面做数据迁移时发现,WindowsServer的多个主机可以进行磁盘共享访问 但是自己设置是灰白无法点击的 文件目录共享还是可以进行设置的 1.找到自己需要共享的目录,右键选择[属性],并找到 ...

  9. 【Hibernate】Re01.5 API

    1.Session单表的CRUD操作 1.增加或者修改,使用同一个方法,或者下面的两个也行: 感觉多此一举... 2.删除方法,硬删除: 3.获取方法提供了两种,Get & Load get方 ...

  10. Python的GDAL库绘制多波段、长时序遥感影像时间曲线图

      本文介绍基于Python中的gdal模块,对大量长时间序列的栅格遥感影像文件,绘制其每一个波段中.若干随机指定的像元的时间序列曲线图的方法.   在之前的文章中,我们就已经介绍过基于gdal模块, ...