std::variant(3)

NAME
std::variant - std::variant

Synopsis
   Defined in header <variant>
   template< class... Types > (since C++17)
   class variant;
   The class template std::variant represents a type-safe union. An instance of
   std::variant at any given time either holds a value of one of its alternative types,
   or in the case of error - no value (this state is hard to achieve, see
   valueless_by_exception).
   As with unions, if a variant holds a value of some object type T, the object
   representation of T is allocated directly within the object representation of the
   variant itself. Variant is not allowed to allocate additional (dynamic) memory.
   A variant is not permitted to hold references, arrays, or the type void.
   A variant is permitted to hold the same type more than once, and to hold differently
   cv-qualified versions of the same type.
   Consistent with the behavior of unions during aggregate initialization, a
   default-constructed variant holds a value of its first alternative, unless that
   alternative is not default-constructible (in which case the variant is not
   default-constructible either). The helper class std::monostate can be used to make
   such variants default-constructible.
   A program that instantiates the definition of std::variant with no template
   arguments is ill-formed. std::variant<std::monostate> can be used instead.
   If a program declares an explicit or partial specialization of std::variant, the
   program is ill-formed, no diagnostic required.

Template parameters
           the types that may be stored in this variant. All types must meet the
   Types - Destructible requirements (in particular, array types and non-object types
           are not allowed).

Member functions
   constructor constructs the variant object
                        (public member function)
   destructor destroys the variant, along with its contained value
                        (public member function)
   operator= assigns a variant
                        (public member function)

Observers
                        returns the zero-based index of the alternative held by the
   index variant
                        (public member function)
   valueless_by_exception checks if the variant is in the invalid state
                        (public member function)

Modifiers
   emplace constructs a value in the variant, in place
                        (public member function)
   swap swaps with another variant
                        (public member function)
         Visitation
   visit calls the provided functor with the argument held by the
   (C++26) variant
                        (public member function)

Non-member functions
   visit calls the provided functor with the arguments held by one or
   (C++17) more variants
                        (function template)
   holds_alternative checks if a variant currently holds a given type
   (C++17) (function template)
   get(std::variant) reads the value of the variant given the index or the type
   (C++17) (if the type is unique), throws on error
                        (function template)
   get_if obtains a pointer to the value of a pointed-to variant given
   (C++17) the index or the type (if unique), returns null on error
                        (function template)
   operator==
   operator!=
   operator<
   operator<=
   operator>
   operator>=
   operator<=> compares variant objects as their contained values
   (C++17) (function template)
   (C++17)
   (C++17)
   (C++17)
   (C++17)
   (C++17)
   (C++20)
   std::swap(std::variant) specializes the std::swap algorithm
   (C++17) (function template)

Helper classes
   monostate placeholder type for use as the first alternative in a
   (C++17) variant of non-default-constructible types
                        (class)
   bad_variant_access exception thrown on invalid accesses to the value of a
   (C++17) variant
                        (class)
   variant_size obtains the size of the variant's list of alternatives at
   variant_size_v compile time
   (C++17) (class template) (variable template)
   variant_alternative obtains the type of the alternative specified by its index,
   variant_alternative_t at compile time
   (C++17) (class template) (alias template)
   std::hash<std::variant> hash support for std::variant
   (C++17) (class template specialization)
   Helper objects
   variant_npos index of the variant in the invalid state
   (C++17) (constant)

Notes
   Feature-test macro Value Std Feature
                      201606L (C++17) std::variant: a type-safe union
                      202102L (C++17) std::visit for classes derived from std::variant
   __cpp_lib_variant (DR)
                      202106L (C++20) Fully constexpr std::variant
                        (DR)
                      202306L (C++26) Member visit

Example
// Run this code
 #include <cassert>
 #include <iostream>
 #include <string>
 #include <variant>
 int main()
 {
     std::variant<int, float> v, w;
     v = 42; // v contains int
     int i = std::get<int>(v);
     assert(42 == i); // succeeds
     w = std::get<int>(v);
     w = std::get<0>(v); // same effect as the previous line
     w = v; // same effect as the previous line
 // std::get<double>(v); // error: no double in [int, float]
 // std::get<3>(v); // error: valid index values are 0 and 1
     try
     {
         std::get<float>(w); // w contains int, not float: will throw
     }
     catch (const std::bad_variant_access& ex)
     {
         std::cout << ex.what() << '\n';
     }
     using namespace std::literals;
     std::variant<std::string> x("abc");
     // converting constructors work when unambiguous
     x = "def"; // converting assignment also works when unambiguous
     std::variant<std::string, void const*> y("abc");
     // casts to void const * when passed a char const *
     assert(std::holds_alternative<void const*>(y)); // succeeds
     y = "xyz"s;
     assert(std::holds_alternative<std::string>(y)); // succeeds
 }

Possible output:
 std::get: wrong index for variant
   Defect reports
   The following behavior-changing defect reports were applied retroactively to
   previously published C++ standards.
      DR Applied to Behavior as published Correct behavior
                       specialization of std::uses_allocator
   LWG 2901 C++17 provided, specialization removed
                       but std::variant cannot properly
                       support allocators
                        the program is ill-formed
   LWG 3990 C++17 a program could declare an explicit or in this
                       partial specialization of std::variant case (no diagnostic
                        required)

See also
   in_place
   in_place_type
   in_place_index in-place construction tag
   in_place_t (tag)
   in_place_type_t
   in_place_index_t
   (C++17)
   optional a wrapper that may or may not hold an object
   (C++17) (class template)
   any objects that hold instances of any CopyConstructible type
   (C++17) (class)