使用选项表示函数的失败
在 C++ 17 之前,函数通常以下列几种方式之一表示失败:
- 返回了一个空指针。
- 例如,在没有委托的
App
实例上调用函数Delegate *App::get_delegate()
将返回nullptr
。 - 对于动态分配或大型并由指针管理的对象,这是一个很好的解决方案,但对于通常通过复制进行堆栈分配和传递的小对象来说,这不是一个好的解决方案。
- 例如,在没有委托的
- 保留返回类型的特定值以指示失败。
- 例如,在两个未连接的顶点上调用函数
unsigned shortest_path_distance(Vertex a, Vertex b)
可能会返回零以指示此事实。
- 例如,在两个未连接的顶点上调用函数
- 该值与
bool
配对,表示返回的值是有意义的。- 例如,使用不是整数的字符串参数调用函数
std::pair<int, bool> parse(const std::string &str)
将返回一个未定义int
和bool
设置为false
的对。
- 例如,使用不是整数的字符串参数调用函数
在这个例子中,John 给了两只宠物,Fluffy 和 Furball。然后调用函数 Person::pet_with_name()
来检索 John 的宠物胡须。由于 John 没有名为 Whiskers 的宠物,因此该功能失败并返回 std::nullopt
。
#include <iostream>
#include <optional>
#include <string>
#include <vector>
struct Animal {
std::string name;
};
struct Person {
std::string name;
std::vector<Animal> pets;
std::optional<Animal> pet_with_name(const std::string &name) {
for (const Animal &pet : pets) {
if (pet.name == name) {
return pet;
}
}
return std::nullopt;
}
};
int main() {
Person john;
john.name = "John";
Animal fluffy;
fluffy.name = "Fluffy";
john.pets.push_back(fluffy);
Animal furball;
furball.name = "Furball";
john.pets.push_back(furball);
std::optional<Animal> whiskers = john.pet_with_name("Whiskers");
if (whiskers) {
std::cout << "John has a pet named Whiskers." << std::endl;
}
else {
std::cout << "Whiskers must not belong to John." << std::endl;
}
}