Before C++17, a function typically represented failure in one of several ways:
Delegate *App::get_delegate()
on an App
instance that did not have a delegate would return nullptr
.unsigned shortest_path_distance(Vertex a, Vertex b)
on two vertices that are not connected may return zero to indicate this fact.bool
to indicate is the returned value was meaningful.
std::pair<int, bool> parse(const std::string &str)
with a string argument that is not an integer would return a pair with an undefined int
and a bool
set to false
.In this example, John is given two pets, Fluffy and Furball. The function Person::pet_with_name()
is then called to retrieve John's pet Whiskers. Since John does not have a pet named Whiskers, the function fails and std::nullopt
is returned instead.
#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;
}
}