...

/

Manage Optional Values with std::optional

Manage Optional Values with std::optional

Learn to manage optional values with std::optional.

We'll cover the following...

Introduced with C++17, the std::optional class holds an optional value.

Consider the case where we have a function that may or may not return a value. For example, a function that checks if a number is prime but returns the first factor if there is one. This function should return either a value or a bool status. We could create a struct that carries both value and status:

struct factor_t {
bool is_prime;
long factor;
};
factor_t factor(long n) {
factor_t r{};
for(long i = 2; i <= n / 2; ++i) {
if (n % i == 0) {
r.is_prime = false;
r.factor = i;
return r;
}
}
r.is_prime = true;
return r;
}

It's a clumsy solution but it works, and it's not uncommon. It could be made a lot simpler with the optional class:

optional<long> factor(long n) {
for (long i = 2; i <= n / 2; ++i) {
if (n % i == 0) return {i};
}
return {};
}

With optional, we can return a value or a non-value. We can call it, like this:

long a{ 42 };
long b{ 73 };
auto x = factor(a);
auto y = factor(b);
if(x) cout << format("lowest factor of {} is {}\n", a, *x);
else cout << format("{} is prime\n", a);
if(y) cout << format("lowest factor of {} is {}\n", b, *y);
else cout << format("{} is prime\n", b);
...
lowest factor of 42 is 2
73 is prime
...