std::optional
是 C++17 引入的模板类,用于表示一个可能包含值或不包含值的容器。它适用于函数可能返回无效结果、对象初始化可能延迟等场景,避免了使用特殊值(如 -1
、nullptr
)或额外的错误标志,使代码更清晰安全。
为啥要引入std::optional
例如在std::optional 出现之前,如果我们要实现一个在vector中查找符合条件的元素并返回值,可能需要以下示例:
std::string GetString(std::vector<std::string>& names, std::string str) {
for (auto &name : names) {
if (name.find(str) != std::string::npos) {
return name;
}
}
return std::string();
}
如果names本身就包含合法的空字符串呢?例如如下代码
std::string GetString(std::vector<std::string>& names, std::string str) {
for (auto &name : names) {
if (name.find(str) != std::string::npos) {
return name;
}
}
return std::string();
}
int main() {
std::vector<std::string> names{ "xiao", "ming", "hong", ""};
std::cout << GetString(names, "xia1") << std::endl;
}
我们就不能得到很明确的结果。
引入了std::optional之后,我们就可以方便的得到很明确的结果:
#include <iostream>
#include <vector>
#include <string>
std::optional<std::string> GetString(std::vector<std::string>& names, std::string str) {
for (auto &name : names) {
if (name.find(str) != std::string::npos) {
return name;
}
}
return std::nullopt;
}
int main() {
std::vector<std::string> names{ "xiao", "ming", "hong", ""};
std::optional<std::string> result = GetString(names, "xi1");
if (result.has_value()) {
std::cout << result.value() << std::endl;
}
else {
std::cout << "find not" << std::endl;
}
}
std::optional的通常用法:
- 创建std::optional对象:
使用 std::optional
的构造函数或工厂函数 std::make_optional
std::optional<int> value1(7);
auto value2 = std::make_optional<int>(7);
- 检查
std::optional
对象是否包含值
1、使用has_value()
#include <optional>
#include <iostream>
#include <string>
int main() {
std::optional<int> value{ 2 };
if (value.has_value()) {
std::cout << "has value" << std::endl;
}
else {
std::cout << "no value" << std::endl;
}
}
2、使用std::optional
重载的 operator bool
#include <optional>
#include <iostream>
#include <string>
int main() {
std::optional<int> value{};
if (value) {
std::cout << "has value" << std::endl;
}
else {
std::cout << "no value" << std::endl;
}
}
- 使用value()方法获取
std::optional
里面包含的值int main() { std::optional<int> value{2}; std::cout << value.value() << std::endl; }
注意:如果value为空,则会导致未定义行为。
-
使用value_or方法获取
std::optional
对象中的值,如果对象为空,则返回一个默认值。#include <optional> #include <iostream> int main() { std::optional<int> value{}; std::cout << value.value_or(-1) << std::endl; }
结果输出-1
-
对
std::optional
对象进行赋
#include <optional>
#include <iostream>
int main() {
std::optional<int> value;
value = 7;
std::cout << value.value() << std::endl;
value.emplace(10);
std::cout << value.value() << std::endl;
}
- 清除
std::optional
对象中的值
#include <optional>
#include <iostream>
int main() {
std::optional<int> value{ 7 };
value.reset();
std::cout << value.has_value() << std::endl;
}