std::optional:解决值存在性问题的利器

背景

查找std::vector内的首个偶数,如果存在则返回该偶数;可是如果std::vecotr内不存在偶数时,该如何?通常是找一些魔幻值/错误码作为返回值,如-1;如如下代码

c 复制代码
//return first even value if exist, else return -1;
intfind_even(std::vector<int> nums)
{
    auto it = std::find_if(nums.begin(), nums.end(), [](intnum) {
        return num % 2 == 0; 
        });


    if (it != nums.end()) {
        return *it;
    }
    else {
        return -1;//magic value
    }
}

可是通常这些魔幻值需要接口使用者遵守函数的约定,为接口的使用增加了复杂度,基于此C++17提出了std::optional,用于解决值可能存在也可能不存在的问题。

std::optional<T>作为一个模板类,用于管理一个可选的容纳值(此处与std::tuple还是有区别的,tuple可以容纳n个值,获取函数执行结果的n种方式),容纳值可以是自定义类型,甚至是另一个optional。其表征含值、不含值两个状态。

使用std::optional优化如上代码,

c 复制代码
std::optional<int> find_even(std::vector<int> nums)
{
    auto it = std::find_if(nums.begin(), nums.end(), [](intnum) {
        return num % 2 == 0; 
        });


    if (it != nums.end()) {
        return *it;
    }
    else {
        returnstd::nullopt;
    }
}


void using_find_even()
{
    std::vector<int> nums = { 1, 3, 5, 7, 9, 2, 4, 6 };
    auto opt = find_even(nums);
    //if (opt)
    if(opt.has_value())
    {
        std::cout<<"exist even num "<<opt.value();
    }
    else
    {
        std::cout<<"no even num in nums";
    }
}

用法

std::optional用法

arduino 复制代码
void using_opt()
{
    std::optional<int> opt1 = 42;
    std::optional<int> opt2{66}; 
    opt2 = std::nullopt; // 将opt2重置为空


    //初始化为空
    std::optional<int> opt3{ std::nullopt };
    std::optional<int> opt4;


    std::optional<int> opt5{88}; 
    std::optional<int>& opt6 = opt5;//opt本身可以是引用


    int x =100;
    //编译错误,不存在引用的optional
    //std::optional<int&> opt7 = x;


    opt5 = 300;//赋值
    opt5.reset();  // 将opt4重置为空


    if (opt1)//判断opt是否存在值
    {
        //value方法取值
        std::cout<<"opt1 has value, and value is "<<opt1.value()<<std::endl;
        //*方法取值
        std::cout << "opt1 has value, and value is " << *opt1 << std::endl;
    }


    if (opt2.has_value())//使用has_value方法判断值是否存在
    {
        std::cout<<"opt has value, and value is "<<opt2.value()<<std::endl;
    }
    else
    {
        std::cout << "opt dont have value \n ";
    }


    //value_or,如果std::optional存在值,则返回其值;否则返回函数的实参10
    auto val = opt3.value_or(10);
}

如上代码几乎涵盖了optional常用的所有用法,如构造、初始化、赋值、判空、取值。

注意

  • std::optional的容纳值不能是引用类型,引用类型会出现编译错误。

  • 获取std::optional的容纳值时,一定要判断optional的是否含值,含值则取其值,不含值时不要取其。,获取不含值的optional内值时会触发std::bad_optional_access异常。

相关推荐
彭祥.14 分钟前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
lzb_kkk31 分钟前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
胖大和尚2 小时前
clang 编译器怎么查看在编译过程中做了哪些优化
c++·clang
钱彬 (Qian Bin)3 小时前
一文掌握Qt Quick数字图像处理项目开发(基于Qt 6.9 C++和QML,代码开源)
c++·开源·qml·qt quick·qt6.9·数字图像处理项目·美观界面
双叶8364 小时前
(C++)学生管理系统(正式版)(map数组的应用)(string应用)(引用)(文件储存的应用)(C++教学)(C++项目)
c语言·开发语言·数据结构·c++
源代码•宸4 小时前
C++高频知识点(二)
开发语言·c++·经验分享
jyan_敬言6 小时前
【C++】string类(二)相关接口介绍及其使用
android·开发语言·c++·青少年编程·visual studio
liulilittle6 小时前
SNIProxy 轻量级匿名CDN代理架构与实现
开发语言·网络·c++·网关·架构·cdn·通信
tan77º7 小时前
【Linux网络编程】Socket - UDP
linux·服务器·网络·c++·udp
GiraKoo7 小时前
【GiraKoo】C++14的新特性
c++