Accessing the value in a std::optional
What is the best way to access the value stored in a std::optional? When should I use value() vs operator*?
There are several ways to access the value stored in a std::optional, each with its own use case:
value()
This returns a reference to the contained value. If the optional is empty, it throws a std::bad_optional_access exception. Use this if you are certain the optional contains a value, and you want an exception if it doesn't.
#include <iostream>
#include <optional>
int main() {
std::optional<int> maybe_int = 10;
std::cout << maybe_int.value(); // prints 10
maybe_int = std::nullopt;
// throws std::bad_optional_access
std::cout << maybe_int.value();
}operator* and operator->
These also return a reference to the contained value, but they do not check whether the optional contains a value. Use these if you are certain the optional contains a value, and you want undefined behavior if it doesn't.
#include <iostream>
#include <optional>
int main() {
std::optional<int> maybe_int = 10;
std::cout << *maybe_int; // prints 10
maybe_int = std::nullopt;
// undefined behavior
std::cout << *maybe_int;
}value_or()
This returns the contained value if the optional has one, otherwise it returns the argument. Use this if you want to provide a default value in case the optional is empty.
#include <iostream>
#include <optional>
int main() {
std::optional<int> maybe_int = 10;
// prints 10
std::cout << maybe_int.value_or(0) << ", ";
maybe_int = std::nullopt;
// prints 0
std::cout << maybe_int.value_or(0);
}10, 0In general, use value() when you expect the optional to have a value and you want an exception if it doesn't. Use operator* or operator-> if you are absolutely certain the optional has a value. Use value_or() when you want to provide a default in case the optional is empty.
Nullable Values, std::optional and Monadic Operations
A comprehensive guide to using std::optional to represent values that may or may not be present.