Section

std::optional

The class template std::optional manages an optional contained value: an object that is either engaged and stores a T, or disengaged and stores no value.

std::optional is primarily used to model “maybe a value” without falling back to sentinel values, out-parameters, or heap allocation. A successful result is stored directly inside the optional object, so the type behaves like an object wrapper rather than a smart pointer.

# Declarations

template< class T >
class optional;

(since C++17)

# Semantic model

  • An engaged optional<T> contains a T nested inside the optional object itself.
  • A disengaged optional<T> contains no T; operator bool() and has_value() report that state.
  • reset() destroys the contained object and returns the optional to the empty state.
  • Checked access goes through value() and throws bad_optional_access if no value is present.
  • Unchecked access goes through operator-> and operator*; these require that a value is already present.
  • Since C++26, optional also models a zero-or-one-element view with begin() and end().

# Template parameters

ParameterDescription
TThe stored value type. T must be destructible. Reference types, array types, function types, void, std::nullopt_t, and std::in_place_t are not valid optional element types.

# Member types

Member typeDefinition
value_typeT
iteratorC++26 iterator type for the zero-or-one-element range view returned by begin()
const_iteratorC++26 const iterator type for the range view

The iterator aliases exist to make optional participate in range-based code as a tiny view, not to turn it into a general-purpose container.

# Member functions

# Special members

MemberPurpose
optional::optionalConstructs an empty optional, copies or moves another optional, or constructs the contained value in place
optional::~optionalDestroys the contained value if one is present
optional::operator=Replaces the state or contained value

# Iterators

MemberPurpose
beginReturns an iterator to the contained element when engaged, otherwise the past-the-end iterator
endReturns the end iterator for the zero-or-one-element range

# Observers

MemberPurpose
operator->, operator*Access the contained value without an emptiness check
operator bool, has_valueReport whether a value is present
valueReturn the contained value with checked access
value_orReturn the contained value or a fallback

# Monadic operations

MemberPurpose
and_thenChains another optional-producing operation when a value is present
transformApplies a transformation to the contained value and wraps the result
or_elseProduces an alternative optional when the current one is empty

These C++23 operations let optional pipelines stay explicit about success and absence without repeated if (opt) scaffolding.

# Modifiers

MemberPurpose
swapExchanges the states and contained values of two optionals
resetDestroys any contained value and leaves the optional disengaged
emplaceConstructs the contained value directly inside the optional

# Non-member functions

FunctionPurpose
comparison operatorsCompare optionals with other optionals, nullopt, or values
make_optionalConstructs an optional while deducing T
std::swap(std::optional)Specialized swap overload for optional

# Helper classes and objects

HelperPurpose
std::hash<std::optional>Hash support for optional
nullopt_tTag type representing an empty optional
bad_optional_accessException thrown by checked access on an empty optional
nulloptConstant used to create or compare against the disengaged state
in_place and related tagsTags used for direct in-place construction

# Helper specializations

  • ranges::enable_view<std::optional<T>> = true makes optional model a view in C++26.
  • format_kind<std::optional<T>> = range_format::disabled disables generic range formatting for optional in C++26.

# Deduction guides

The class has deduction guides so direct construction such as std::optional o(std::string{"x"}); can infer the stored type without spelling T explicitly.

# Notes

Feature-test macroValueStandardMeaning
__cpp_lib_optional201606LC++17std::optional
__cpp_lib_optional202106LC++23 (DR20)fully constexpr optional
__cpp_lib_optional202110LC++23monadic operations
__cpp_lib_optional_range_support202406LC++26range support for std::optional

optional expresses absence, but not the reason for absence. If the caller needs structured error information rather than a simple engaged/disengaged state, std::expected is usually a better fit.

# Example

#include <iostream>
#include <optional>
#include <string>
 
// optional can be used as the return type of a factory that may fail
std::optional<std::string> create(bool b)
{
    if (b)
        return "Godzilla";
    return {};
}
 
// std::nullopt can be used to create any (empty) std::optional
auto create2(bool b)
{
    return b ? std::optional<std::string>{"Godzilla"} : std::nullopt;
}
 
int main()
{
    std::cout << "create(false) returned "
              << create(false).value_or("empty") << '\n';
 
    // optional-returning factory functions are usable as conditions of while and if
    if (auto str = create2(true))
        std::cout << "create2(true) returned " << *str << '\n';
}

# See also