std::variant
|   Defined in header  <variant>
  | 
||
|   template <class... Types> class variant;  | 
(since C++17) | |
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. Empty variants are also ill-formed (std::variant<std::monostate> can be used instead).
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.
Template parameters
| Types | - | the types that may be stored in this variant. All types must be (possibly cv-qualified) non-array object types. | 
Member functions
|   constructs the variant object  (public member function)  | |
|   destroys the variant, along with its contained value  (public member function)  | |
|    assigns a variant   (public member function)  | |
 Observers | |
|    returns the zero-based index of the alternative held by the variant  (public member function)  | |
|    checks if the variant is in the invalid state  (public member function)  | |
 Modifiers | |
|    constructs a value in the variant, in place  (public member function)  | |
|    swaps with another variant  (public member function)  | |
Non-member functions
|    (C++17)  | 
   calls the provided functor with the arguments held by one or more variants   (function template)  | 
|    (C++17)  | 
   checks if a variant currently holds a given type  (function template)  | 
|    (C++17)  | 
  reads the value of the variant given the index or the type (if the type is unique), throws on error   (function template)  | 
|    (C++17)  | 
  obtains a pointer to the value of a pointed-to variant given the index or the type (if unique), returns null on error  (function template)  | 
   compares variant objects as their contained values (function template)  | |
|    (C++17)  | 
   specializes the std::swap algorithm  (function)  | 
Helper classes
|    (C++17)  | 
   placeholder type for use as the first alternative in a variant of non-default-constructible types  (class)  | 
|    (C++17)  | 
   exception thrown on invalid accesses to the value of a variant  (class)  | 
|    (C++17)  | 
  obtains the size of the variant's list of alternatives at compile time   (class template) (variable template)  | 
|    obtains the type of the alternative specified by its index, at compile time   (class template) (alias template)  | |
|    (C++17)  | 
  specializes the std::hash algorithm   (class template specialization)  | 
Helper objects
|    (C++17)  | 
   index of the variant in the invalid state  (constant)  | 
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior | 
|---|---|---|---|
| LWG 2901 | C++17 |  specialization of std::uses_allocator provided, but variant can't properly support allocators
 | 
specialization removed | 
Example
#include <variant> #include <string> #include <cassert> int main() { std::variant<int, float> v, w; v = 12; // v contains int int i = std::get<int>(v); 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&) {} 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 }
 
See also
|    in-place construction tag   (class template)  | |
|    (C++17)  | 
   a wrapper that may or may not hold an object   (class template)  | 
|    (C++17)  | 
   Objects that hold instances of any CopyConstructible type.   (class)  |