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 273 is prime
...