使用選項表示函式的失敗
在 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;
}
}