(C++17) optional的使用

编程入门 行业动态 更新时间:2024-10-26 15:27:36

(C++17) <a href=https://www.elefans.com/category/jswz/34/1761889.html style=optional的使用"/>

(C++17) optional的使用

文章目录

  • 前言与需求
  • 使用
    • 简单示例
    • 构造
      • 空值
      • std::in_place 原位构造
      • 推导指引
      • std::make_optional
    • 访问
      • 取值
      • 逻辑判断
  • END

前言与需求

optional 》adj.可选择的,选修的

在编程与实际项目中,可能会出现数据不合法的需求与状态。

在以往通常的使用中,通常会为每种数据类型定义一个值作为不合法的标志。比如int = -1, string = “str_invalid”等等。

这种方式有许多弊端:

  1. 编写时麻烦
  2. 这些不合法数据在有的场景下可能是有效的
  3. 团队协作时需要来回确认
  4. 等等

为了处理这种可能出现不合法的情况,C++17推出了std::opational<>来处理这个问题。

在C++20和C++23对此还进行了加强,但本文不对这些加强做过多演示。

使用

std::optional - cppreference

简单示例

该实例简洁明了,能够基本了解optional的使用大意。

注意在optional是空值时,如还需要取值则会出现异常

terminate called after throwing an instance of ‘std::bad_optional_access’
what(): bad optional access

#include <iostream>
#include <optional>
#include <string>std::optional<std::string> create_optional(bool flag) {if (flag) {return "pass option";} else {// {} 也可行// return {};return std::nullopt;}
}void test(bool flag) {auto opt = create_optional(flag);// 可以直接作为if判断if (opt) {// 两种取值方法std::cout << opt.value() << std::endl;std::cout << *opt << std::endl;// 可以修改opt.value() = "modify opt.value()";std::cout << opt.value_or("no data") << std::endl;} else {// terminate called after throwing an instance of// 'std::bad_optional_access'//  what():  bad optional access// std::cout << opt.value() << std::endl;std::cout << opt.value_or("no data") << std::endl;}
}int main() {test(true);test(false);
}

构造

空值

#include <iostream>
#include <optional>
#include <string>int main() {std::optional<std::string> op0;std::optional<std::string> op1 = {};std::optional<std::string> op2 = std::nullopt;
}

std::in_place 原位构造

原位构造。使用std::in_place可以直接使用构造函数了。

#include <iostream>
#include <optional>
#include <string>int main() {// 调用 std::string( initializer_list<CharT> ) 构造函数std::optional<std::string> opt1(std::in_place, {'a', 'b', 'c'});// 调用 std::string( size_type count, CharT ch ) 构造函数std::optional<std::string> opt2(std::in_place, 3, 'A');std::cout << opt1.value() << '\n' << opt2.value() << std::endl;
}

推导指引

都C++17了,推到指引必不可少

注意数组还是退化成 T*

#include <optional>
#include <string>int main() {int arr[2];// std::optional<int *> optstd::optional opt{arr};// class std::optional<const char *>std::optional str = "abc";using namespace std::literals;// class std::optional<std::string>std::optional str_i = "abc"s;
}

std::make_optional

用对应的make函数进行构造。

#include <iomanip>
#include <iostream>
#include <optional>
#include <string>
#include <vector>int main() {auto opt = std::make_optional<std::vector<int>>(5, 2);for (int i : *opt) {std::cout << i << " ";}std::cout << std::endl;std::string str{"hello world"};auto        opts = std::make_optional<std::string>(std::move(str));std::cout << std::quoted(opts.value_or("empty value"))<< std::endl;std::cout << str << std::endl;
}

访问

取值

直接使用operator*()或者value()即可

注意,考虑空值时需要套用上带默认值版本的value_or()

#include <iostream>
#include <optional>
#include <string>int main() {auto opt = std::make_optional<std::string>("Hello World");std::cout << opt.value() << std::endl;std::cout << *opt << std::endl;std::cout << opt.value_or("no data") << std::endl;// 都可以修改// opt.value() = "modify data";*opt = "modify data";if (opt.has_value()) {std::cout << opt.value_or("no data") << std::endl;}// 重置opt.reset();std::cout << opt.value_or("no data") << std::endl;// 异常// terminate called after throwing an instance of 'std::bad_optional_access'// what():  bad optional access// std::cout << opt.value() << std::endl;
}

逻辑判断

因为有operator bool()所以可以直接在if等逻辑判断中使用。

#include <iostream>
#include <optional>
#include <string>int main() {auto opt = std::make_optional<std::string>("Hello World");if (opt.has_value()) {std::cout << opt.value_or("no data") << std::endl;}if (opt) {std::cout << opt.value_or("no data") << std::endl;}
}



END

更多推荐

(C++17) optional的使用

本文发布于:2023-11-15 20:57:17,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1606227.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:optional

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!