• C++(25): C++17探索:std::optional


    1. 概述

            std::optional是C++17标准引入的一个新的标准库组件。这是一个轻量级的容器,旨在以类型安全的方式包装可能为空的值。std::optional为处理可能缺失的数据提供了一种优雅而简洁的方法,这在以往通常需要使用专门的“存在”标志或复杂的错误处理机制。

            简单点讲,std::optional在使用上并不复杂,主要用来替代那些需要返回NULL,或以返回-1表示错误等的场合。这样做最直观的一个改进就是易读性增强了。

    2. 为什么需要std::optional?

            在C++中,函数通常返回一个值或者在失败时返回一个特殊值(如NULL或-1)。这种方法存在几个问题:

    (1)类型不安全:返回特殊值通常意味着函数返回的类型与实际返回值的类型不一致,这可能导致类型安全问题。

    (2)语义不明确:使用特殊值来表示错误状态可能会与合法的返回值冲突。

    (3)错误处理复杂:调用者需要检查返回的特殊值,并进行额外的错误处理。

            std::optional提供了一种更好的解决方案,它允许函数明确地表达它们可能不返回有效值的情况。

    3. std::optional的基本概念

            std::optional是一个模板类,其中T是被包装的值的类型。它包含以下两个主要状态:

    无值状态:表示不包含有效的T类型对象。

    有值状态:包含一个有效的T类型对象。

    4. 使用std::optional

    (1)构造

    1. std::optional<int> opt; // 默认构造,无值状态
    2. std::optional<int> opt(10); // 有值状态,包含值10

    (2)有无值判断has_value()

            返回一个布尔类型,如果当前容器是有值状态,返回true,否则返回false。

            使用方法如下:

    1. if (opt.has_value()) {
    2. // opt包含一个值
    3. }

            需要注意的是,当我们想要访问std::optional类型的值时,需要先判断是否有值,否则会出现未定义行为。

    (3)使用operator*或value()访问存储的值

            首先我们需要判断是否有值,然后再进行访问。

            或者添加异常捕获单元。

    1. #include
    2. #include
    3. int main(int argc, char* argv[])
    4. {
    5. std::optional<int> opt(10);
    6. if (opt) {
    7. std::cout << "Value: " << *opt << std::endl; ///< 输出 10
    8. }
    9. return 0;
    10. }

    1. int main(int argc, char* argv[])
    2. {
    3. std::optional<int> opt;
    4. try {
    5. int value = opt.value(); ///< 这里会抛出异常
    6. } catch (const std::bad_optional_access& e) {
    7. std::cerr << "Exception: " << e.what() << std::endl;
    8. }
    9. return 0;
    10. }

    (4)value_or(T default):返回存储的值,如果std::optional处于无值状态,则返回提供的默认值。

    int value = opt.value_or(-1);  ///< 返回10,如果opt无值则返回-1

    (5)reset():将std::optional重置为无值状态。

    opt.reset();  ///< opt变为无值状态

    (6)emplace():在原地构造一个新值,如果std::optional已经有值,则先销毁旧值。

    opt.emplace(20);  // opt现在包含20
  • 相关阅读:
    docker安装Redis
    如何备份Syslog配置文件?
    容器化 | 在 KubeSphere 中部署 MySQL 集群
    C++STL——vector的模拟实现(代码+解析)
    C语言:用函数删除字符串里面的空格
    容器化 Spring Boot 代码的 9 个技巧
    统计数(C++)
    最新研究综述——探索基础模型中的“幻觉”现象
    http 403
    【450. 删除二叉搜索树中的节点】
  • 原文地址:https://blog.csdn.net/tecsai/article/details/139252765