Using optionals to represent the failure of a function
suggest changeBefore C++17, a function typically represented failure in one of several ways:
- A null pointer was returned.
* e.g. Calling a function `Delegate *App::get_delegate()` on an `App` instance that did not have a delegate would return `nullptr`.
* This is a good solution for objects that have been dynamically allocated or are large and managed by pointers, but isn't a good solution for small objects that are typically stack-allocated and passed by copying.
- A specific value of the return type was reserved to indicate failure.
- e.g. Calling a function
unsigned shortest_path_distance(Vertex a, Vertex b)
on two vertices that are not connected may return zero to indicate this fact. - The value was paired together with a
bool
to indicate is the returned value was meaningful. - e.g. Calling a function
std::pair<int, bool> parse(const std::string &str)
with a string argument that is not an integer would return a pair with an undefinedint
and abool
set tofalse
.
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;
}
}
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents