IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++17新特性——std::optional -> 正文阅读

[C++知识库]C++17新特性——std::optional

目录

一、前言

二、optional的使用

三、解决前言中的问题


一、前言

我们在写代码过程中可能经常会碰到这样的情况:

某个函数经过一系列计算后获取一个返回值,但是这个函数可能在执行过程中有异常分支,从这些异常分支中return出来的时候还没有得到这个想计算的值。? 例如想计算得到一个无符号类型,我们可能会在这些异常分支return一个-1出去,用来表示计算失败,或执行有误,甚至不同的负值用来表示不同的异常情况。。。由于这些值的存在,本来返回值应该是uint32类型,为了容纳可能出现的负值和整个uint32的范围,返回值就变成了int64。。。这个int64,竟然要么表示错误码,要么表示计算结果?这给阅读和使用上都造成了不便。此外,这种负值的出现还引入了魔鬼数字。

举个栗子:(伪代码,并不能跑,只是用作举例)

#include <cstdint>

int64_t getUintValue() {
    if (xxx) {
        return -1; // malloc fail
    }
    if (xxx) {
        return -2; // invalid param
    }
    // do some work
    return someValue;
}

或者是一个计算布尔值的函数,失败时也返回false吗?调用者拿到这个值一脸懵逼。。

bool getBoolValue() {
    if (xxx) {
        return false;  // 计算失败时返回的false
    }
    // do some work
    return false;  // 计算成功时返回的false
}

还有一种情况发生在枚举中。通常为了应对枚举类型暂时还不知道时,我们会新增一个枚举值叫UNKNOWN。这样以来,任何一个使用该枚举类型的地方都要首先判断是不是UNKNOWN,造成代码冗余。举个栗子:

enum Color {
    RED,
    BLUE,
    GREEN,
    UNKNOWN
};

void printColor(Color c) {
    // 这里还要不要判断是不是UNKNOWN?
    // 如果不判断,其它地方复用这个函数时怎么办?
}

void judgeColor(Color c) {
    if (c != UNKNOWN) {
        printColor(c);
    }
}

C++17新增了std::optional来解决这个问题。

二、optional的使用

(gcc7/clang4/msvc19.10以上才支持optional,首先先检查你的编译器版本)

optional是一个模板类:

template <class T>
class optional;

它内部有两种状态,要么有值(T类型),要么没有值(std::nullopt)。有点像T*指针,要么指向一个T类型,要么是空指针(nullptr)。

std::optional有以下几种构造方式:

#include <iostream>
#include <optional>
using namespace std;

int main() {
    optional<int> o1;  //什么都不写时默认初始化为nullopt
    optional<int> o2 = nullopt;  //初始化为无值
    optional<int> o3 = 10;  //用一个T类型的值来初始化
    optional<int> o4 = o3;  //用另一个optional来初始化
    return 0;
}

查看一个optional对象是否有值,可以直接用if,或者用has_value()

#include <iostream>
#include <optional>
using namespace std;

int main() {
    optional<int> o1;
    if (o1) {
        printf("o1 has value\n");
    }
    if (o1.has_value()) {
        printf("o1 has value\n");
    }
    return 0;
}

当一个optional有值时,可以通过用指针的方式(*号和->号)来使用它,或者用.value()拿到它的值:

#include <iostream>
#include <optional>
#include <string>
using namespace std;

int main() {
    optional<int> o1 = 5;
    printf("%d\n", *o1);
    optional<string> o2 = "hello";
    printf("%s\n", o2->c_str());
    printf("%s\n", o2.value().c_str());
    return 0;
}

将一个有值的optional变为无值,用.reset()。该函数会将已存储的T类型对象析构

#include <iostream>
#include <optional>
using namespace std;

int main() {
    optional<int> o1 = 5;
    o1.reset();
}

三、解决前言中的问题

于是在第一章中的3个问题可以这样改写:

#include <cstdint>
#include <optional>
using namespace std;

optional<uint32_t> getUintValue() {
    if (xxx) {
        return nullopt; // malloc fail
    }
    if (xxx) {
        return nullopt; // invalid param
    }
    // do some work
    return someValue;
}
#include <optional>
using namespace std;

optional<bool> getBoolValue() {
    if (xxx) {
        return nullopt;  // 计算失败时返回
    }
    // do some work
    return false;  // 计算成功时返回的false
}
#include <optional>
using namespace std;

enum Color {
    RED,
    BLUE,
    GREEN
};

void printColor(Color c) {
    // 这里永远都不需要判断这个值是否合法
}

void judgeColor(optional<Color> c) {
    if (c.has_value()) {
        printColor(c.value());
    }
}

可读性暴增!

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-05 20:18:22  更:2021-07-05 20:18:44 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/25 16:01:46-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计