「C/C++」C++17 之 std::optional 值管理器(判断值存不存在)

#1024程序员节|征文#
在这里插入图片描述

在这里插入图片描述

✨博客主页
何曾参静谧的博客
📌文章专栏
「C/C++」C/C++程序设计
📚全部专栏
「VS」Visual Studio「C/C++」C/C++程序设计「UG/NX」BlockUI集合
「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发
「QT」QT5程序设计「File」数据文件格式「PK」Parasolid函数说明

std::optional容器详解

1. 引用头文件

std::optional是C++17标准库引入的一个模板类,用于表示一个值可能存在也可能不存在。要使用std::optional,首先需要包含头文件<optional>

#include <optional>

2. 注意事项

  • 空值检查:在访问std::optional的值之前,必须检查它是否包含值,否则会导致未定义行为。
  • 生命周期:std::optional的生命周期与它包含的值的生命周期一致,不能返回包含局部变量的std::optional。
  • 线程安全:std::optional本身不提供线程同步机制,在多线程环境中使用时需要额外的同步措施。

3. 函数构造

std::optional的构造方式多样,包括默认构造、值构造和使用std::nullopt构造。

std::optional<int> opt1; // 默认构造,无值状态
std::optional<int> opt2(10); // 值构造,包含值10
std::optional<int> opt3 = std::nullopt; // 无值状态,相当于默认构造

4. 对象初始化

std::optional对象可以通过多种方式初始化,包括直接赋值、emplace构造等。

std::optional<int> opt4;
opt4 = 20; // 直接赋值

std::optional<std::string> opt5;
opt5.emplace("Hello, World!"); // 使用emplace构造值

5. 元素访问

访问std::optional的值可以使用*运算符或value()方法,但需要先检查是否有值。使用value_or()时可以指定值不存在返回的值。

std::optional<int> opt2 = 10;
if (opt2) {
    std::cout << "Value: " << *opt2 << std::endl; // 输出10
}
std::optional<int> opt3;
try {
    std::cout << "Value or default: " << opt3.value_or(-1) << std::endl; // 输出-1
} catch (const std::bad_optional_access& e) {
    std::cerr << "Exception: " << e.what() << std::endl;
}

6. 迭代器

std::optional不是一个容器,而是一个可能包含单个值的包装器,因此它没有迭代器。

7. 容器

虽然std::optional本身不是一个容器,但它可以作为一个容器的一部分,例如std::vector<std::optional<T>>

std::vector<std::optional<int>> vec = {1, std::nullopt, 3};

8. 修改器

std::optional提供了多种修改器,包括重新赋值、重置为无值状态、交换值等。

std::optional<int> opt6(10);
opt6 = 20; // 重新赋值
opt6.reset(); // 重置为无值状态

std::optional<int> opt7(30);
std::optional<int> opt8(40);
opt7.swap(opt8); // 交换值

9. 元素比较

std::optional支持相等性比较,两个std::optional对象只有在都为空或都持有相等的值时才相等。

std::optional<int> opt9(10);
std::optional<int> opt10(10);
std::optional<int> opt11;

if (opt9 == opt10) {
    std::cout << "opt9 and opt10 are equal." << std::endl;
}

if (!opt9 || !opt11 || opt9 != opt11) {
    std::cout << "opt9 and opt11 are not equal or one of them is empty." << std::endl;
}

10.元素判断

#include <iostream>  
#include <optional>  
  
int main() {  
    std::optional<int> opt1; // 默认构造的 std::optional 是空的  
    std::optional<int> opt2 = 42; // 包含一个值  
  
    if (opt1.has_value()) {  
        std::cout << "opt1 has a value: " << opt1.value() << std::endl;  
    } else {  
        std::cout << "opt1 is empty" << std::endl;  
    }  
  
    if (opt2.has_value()) {  
        std::cout << "opt2 has a value: " << opt2.value() << std::endl;  
    } else {  
        std::cout << "opt2 is empty" << std::endl;  
    }  
  
    return 0;  
}

总结

std::optional是C++17引入的一个非常有用的工具,它提供了一种优雅的方式来表示可能存在,也可能不存在的值。它避免了使用特殊值(如NULL或-1)来表示“无值”状态所带来的类型不安全、语义不明确和错误处理复杂等问题。std::optional的使用场景广泛,包括但不限于函数返回值、配置项可能未设置时、缓存结果可能不存在时等。

应用场景

  1. 函数返回值:当函数可能不返回有效结果时,可以使用std::optional表示返回值是可选的。
  2. 配置项:在读取配置文件时,某些配置项可能未设置,可以使用std::optional来表示这些配置项的值。
  3. 缓存结果:在缓存系统中,某些查询结果可能不存在,可以使用std::optional来表示这些结果。
  4. 延迟初始化:在某些情况下,对象的初始化可能依赖于某些条件,可以使用std::optional来处理延迟初始化。

std::optional的引入使得C++的类型系统更加完善,代码更加清晰和易于维护。


在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何曾参静谧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值