C++ std::optional:优雅处理可选值 #
引言 #
前几天交流群里看到老王在聊C++的tuple,说tuple非常好用,我在群里向老王推荐使用optional,但没想到,老王居然不知道optional,所以我想,有必要输出一篇文章介绍下optional。希望更多的人都能在开发中用上optional这种高级实用的特性。
How:如何使用std::optional #
optional 是C++17引入的新特性,它是个模板类std::optional,它提供了一个可选的值,可以表示一个变量可能有值,也可能没有值。
它有几个基本用法:
初始化:可以直接初始化 std::optional 为某个值,或者不初始化(此时为 std::nullopt)。
访问:可以通过 .value() 方法获取值,或者使用 -> 操作符访问内部对象,或者使用.value_or()获取值,如果没有值,会自动返回or配置的值。
检查:使用 .has_value() 来检查 std::optional 是否包含值。
When:何时使用std::optional #
有很多场景下,我们都可以考虑使用optional,或者可以说,很多场景下,只有使用optional才是合适的:
某个函数,它某些情况下需要返回值,某些情况下不需要返回值
需要表示一个可能不存在的值
想要避免使用指针来表示可能为空的情况。
Why:为什么使用std::optional #
我整理了几个原因:
可以避免空指针异常:传统的使用指针来表示可选值的方法可能会引起空指针异常,而std::optional提供了一种类型安全的方式来处理这种情况。
代码更加清晰:可以明确的表示某个值是可选的,以前用指针表示的时候,我们不太清楚nullptr的返回究竟是正常情况还是异常情况,而有了optional,我们可以清晰的知道,这个就是可选值。
类型安全:提供了类型安全的方式来处理可能为空的值。
实际代码示例
#include <iostream>
#include <optional>
// 函数可能返回一个整数,也可能不返回
std::optional<int> get_optional(bool return_value) {
if (return_value) {
return 42; // 返回一个值
} else {
return std::nullopt; // 不返回值
}
}
int main() {
auto value = get_optional(true); // 有值
if (value) {
std::cout << "Value is: " << *value << std::endl;
} else {
std::cout << "No value" << std::endl;
}
auto no_value = get_optional(false); // 无值
if (no_value) {
std::cout << "Value is: " << *no_value << std::endl;
} else {
std::cout << "No value" << std::endl;
}
return 0;
}
思考题 #
std::optional是C++17引入的新特性,如果我们不用C++17,难道就没法用了吗?自己实现一个可行吗?