首页 > 其他分享 >std optional 的使用

std optional 的使用

时间:2025-01-02 22:26:43浏览次数:8  
标签:std opt 有值 value 使用 optional cout

std optional 的使用

文章目录

std::optional 是 C++17 引入的一个标准库模板类,它提供了一种方式来表示一个值可能存在也可能不存在(即它的值是“可选的”)。它可以用于表示函数返回值可能为空的情况,避免直接使用指针或特殊值(如 nullptr-1)来表示缺失的值。

1. std::optional 基本概念

std::optional<T> 是一个模板类,其中 T 是存储类型。当 std::optional 对象有值时,您可以像普通对象一样访问它的值;如果它没有值,则它处于“无效”状态。

它提供了两种状态:

  • 有值:表示该 optional 存储了一个类型为 T 的值。
  • 无值:表示该 optional 没有值,可以认为它是“空的”或“未定义的”。

2. std::optional 的基本用法

定义和初始化

#include <iostream>
#include <optional>

std::optional<int> get_value(bool should_return_value) {
    if (should_return_value) {
        return 42;  // 有值
    } else {
        return std::nullopt;  // 没有值
    }
}

int main() {
    auto val1 = get_value(true);  // 有值
    auto val2 = get_value(false); // 没有值
    if (val1) {
        std::cout << "val1: " << *val1 << std::endl;  // 解引用获取值
    } else {
        std::cout << "val1 is empty" << std::endl;
    }
    if (val2) {
        std::cout << "val2: " << *val2 << std::endl;
    } else {
        std::cout << "val2 is empty" << std::endl;
    }
    return 0;
}

在这个例子中,get_value 函数根据 should_return_value 参数的值来返回一个 std::optional<int>。如果返回值存在,就通过 return 42 返回一个有值的 optional;如果返回值不存在,使用 std::nullopt 表示返回一个没有值的 optional

使用 std::optional 的成员函数

std::optional 提供了许多成员函数用于操作 optional 对象:

  • has_value():检查 optional 是否有值。返回 true 表示有值,false 表示没有值。
  • value():如果 optional 有值,返回存储的值;否则抛出 std::bad_optional_access 异常。
  • value_or(T&& default_value):如果 optional 有值,返回存储的值;否则返回提供的默认值。
  • operator*operator->:可以解引用 optional 以访问存储的值。
std::optional<int> maybe_value = 10;

if (maybe_value.has_value()) {
    std::cout << "Value: " << maybe_value.value() << std::endl;
} else {
    std::cout << "No value!" << std::endl;
}

std::optional<int> empty_value;
std::cout << "Value or default: " << empty_value.value_or(42) << std::endl;  // 输出 42

3. std::optional 常用操作

  • 初始化
    • std::optional<T> opt; // 默认构造,表示没有值
    • std::optional<T> opt = T(10); // 使用值初始化,表示有值
    • std::optional<T> opt = std::nullopt; // 无值
  • 检查是否有值
if (opt) {  // 或者 if (opt.has_value())
    std::cout << *opt << std::endl;
}
  • 解引用和访问值
if (opt) {
    std::cout << *opt << std::endl;  // 解引用
}
  • 提供默认值
int value = opt.value_or(100);  // 如果没有值,返回 100
  • 重置值
opt.reset();  // 使 opt 变为没有值的状态

4. 使用 std::optional 的注意事项

  • 访问值时要小心std::optional 可能没有值,直接访问没有值的 optional(例如,使用 optopt.value())会导致未定义行为或抛出异常。因此,通常需要先检查 optional 是否有值。
if (opt) {
    std::cout << *opt << std::endl;
} else {
    std::cout << "opt does not have a value" << std::endl;
}
  • 使用默认值: 使用 value_or 可以提供一个默认值,避免异常抛出或访问无值的情况。
int value = opt.value_or(42);  // 如果没有值,则返回 42
  • 性能考虑: 使用 std::optional 会有一些额外的内存开销,因为它需要在内部存储一个标志来指示是否有值。对于基本类型,optional 会比直接使用值类型稍微慢一些。对于大型对象或者需要多次检查值的场景,可以考虑优化设计,减少不必要的 optional 使用。
  • 与指针的比较std::optional<T> 与指针(如 std::unique_ptr<T> 或裸指针)有所不同。optional 只是表示一个值的“缺席”,而指针可能指向 nullptr 或指向一个对象。在设计中,根据需要选择是否使用 optional 或指针。
  • 不能用作容器的成员: 由于 std::optional 本身是一个包含类型的容器,不能将它作为容器成员来存储其他对象(例如 std::vector<std::optional<T>>),否则会增加额外的内存开销和复杂度。可以考虑其他方式来存储可选类型。

总结

std::optional 是 C++17 中非常有用的工具,能够优雅地处理“可能无值”的情况。它通过明确的 API 提供了检查值存在与否、访问值、提供默认值等功能,减少了使用裸指针或特殊值来表示缺失值的错误。使用时要注意检查 optional 是否有值,避免访问无值的状态导致的异常或错误。

标签:std,opt,有值,value,使用,optional,cout
From: https://blog.csdn.net/weixin_45882303/article/details/144896256

相关文章

  • U8G2库使用案例(stm32)
    U8G2官网:自己移植的U8g2库,OLED库超好用,自己封装了用户层不需要再去查资料使用,注释写的很多很详细,有示例上手就会,初始化也很简单个人移植的U8g2库:超简单的stm32U8g2移植 大家可以自己去官网移植,也可以用我的     U8G2官网 简单的波形生成和显示程序:#i......
  • 在FreeRTOS中使用HAL_UART_Transmit函数时
    voidSeria2_Printf(char*format,...){ charString[200]; va_listarg; va_start(arg,format); vsprintf(String,format,arg); va_end(arg); HAL_UART_Transmit(&huart2,(uint8_t*)&String,strlen(String),HAL_MAX_DELAY);}在FreeRTOS中使用HAL_UART_Tra......
  • 使用Python自动生成历史发表博客目录列表,并计算出单篇访问量、点赞量、收藏量topN生成
    使用Python自动生成历史发表博客目录列表,并计算出单篇访问量、点赞量、收藏量topN生成目录并绘制折线图展示效果图2024博客列表按发表时间顺序从1月到12月2024年01月2024年02月2024年03月2024年04月2024年05月2024年06月2024年07月2024年08月2024年09月2024年10月2024年1......
  • 使用ClosedXML实现Excel导入导出
    使用ClosedXML实现Excel导入导出写在开头游览Dotnet基金会中的项目时,发现了这个库,Github链接,它的性能非常好,详细见下图话不多说,直接上代码吧!导出后端:publicstaticbyte[]Output<T>(List<T>data,stringsheetName){usingvarworkbook=newXLWorkb......
  • Java中使用JFreeChart生成甘特图
    引言甘特图是一种流行的项目管理工具,用于显示项目的进度和任务分配。它通过条形图显示任务的开始和结束时间,使项目经理能够直观地了解项目的整体情况。在Java开发中,JFreeChart是一个强大的开源图表库,能够生成各种类型的图表,包括甘特图。本文将详细介绍如何在Java中使用JFreeChart......
  • 【Cesium】二、vite+vue3+cesium 使用,项目中使用cesium 地图,具体步骤。快速搭建Cesium
    文章目录一、准备项目二、安装三、修改App.vue四、启动项目五、消除控件六、修改底图一、准备项目这里我已经创建好vite+vue3项目模板了,需要可以直接克隆下来,进行下面步骤。vite-commit:点击跳转GitHub二、安装下载依赖yarnaddcesiumvite-plugin-cesiumvite......
  • IntelliJ IDEA 2024 安装激活详细使用教程(激活至2026,实测是永久,亲测!)
    开发工具推荐:IntelliJIDEA2024安装激活详细使用教程(激活至2026,实际上永久,亲测!)申明:本教程IntelliJIDEA补丁、激活码均收集于网络,请勿商用,仅供个人学习使用,如有侵权,请联系作者删除。若条件允许,希望大家购买正版!卸载老版本IDEA首先,如果小伙伴的电脑上有安装老版本的ID......
  • Openwrt 下SRS编译安装及配置使用问题总结
    Openwrt下SRS编译安装及配置使用问题总结基本概念应用背景Openwrt安装SRS方案方案一:交叉编译(失败,不推荐)方案二:目标板编译(编译成功,运行失败,不推荐)安装依赖源码安装问题解决Buildingopenssl-1.1-fit.Can'tlocateFindBin.pmin@INC(youmayneedto......
  • shell脚本的使用
    一、思维导图 二、小练习1、在家目录下创建目录文件dir1,把/etc/passwd拷贝到dir1中,把/etc/group拷贝到dir1中并重命名为grp.txt,使用tree指令,显示dir1目录的文件树,把dir1,分别压缩为dir1.tar.xz,dir1.tar.gz,dir1.tar.bz2#!/bin/bashmkdirdir1cp/etc/group/home/ubuntu/d......
  • JavaScript代码安全性提升:选择和使用JS混淆工具的指南
    https://toolin.cn/jsfuck https://maimai.cn/article/detail?fid=1827257627&efid=382Pa05uQ_i7jAl6rmq5tg 在Web开发中,JavaScript是一种常用的脚本语言,然而,由于其代码容易被他人轻易获取和修改,为了保护JavaScript代码的安全性和版权,我们需要使用JS混淆工具。本文将介绍什......