std::optional
, introduced in C++17, is a template class that provides a way to represent 'optional' values. An std::optional
object can either contain a value or not. This is particularly useful in situations where a value might be missing or not applicable.
Here's a breakdown of how std::optional
is used, with various examples:
-
Initialization and Assignment
#include <optional> std::optional<int> opt; // An empty optional opt = 5; // Assigning a value
-
Accessing the Value
if (opt) { // Check if there's a value std::cout << *opt << std::endl; // Access the value }
-
Using
value()
andvalue_or()
std::cout << opt.value() << std::endl; // Throws std::bad_optional_access if empty std::cout << opt.value_or(0) << std::endl; // Returns 0 if opt is empty
-
With Custom Types
struct MyStruct { int x; }; std::optional<MyStruct> optStruct; optStruct.emplace(MyStruct{10}); // Constructing in-place
-
Returning
std::optional
from Functionsstd::optional<int> findValue(bool condition) { if (condition) return 42; // Found value return {}; // Return empty optional }
-
Chaining Optionals
std::optional<int> opt1 = 10; std::optional<int> opt2 = opt1.value_or(0) + 5; // Chaining with addition
-
Using with STL Containers
std::vector<std::optional<int>> vec = {1, std::nullopt, 3}; for (const auto& val : vec) { if (val) { std::cout << *val << " "; } }
-
Resetting an Optional
opt.reset(); // Removes the contained value, if any
- Error Handling: Use
std::optional
to represent the result of a function that might fail to produce a value, instead of using sentinel values or exceptions. - Lazy Initialization: Delay the construction of an object until it's actually needed.
- APIs with Optional Parameters: Functions can return
std::optional
to indicate optional parameters or results.
std::optional
is a powerful feature that makes your code more expressive and safe by explicitly handling the presence or absence of values.