sumty  0.1.0
Better sum types for C++
variant< T > Class Template Reference

General discriminated union. More...

#include <sumty/variant.hpp>

Inheritance diagram for variant< T >:
Collaboration diagram for variant< T >:

Public Member Functions

constexpr variant () CONDITIONALLY_NOEXCEPT
 Default constructor. More...
 
constexpr variant (const variant &)
 Copy constructor. More...
 
constexpr variant (variant &&)
 Move constructor. More...
 
template<size_t IDX, typename... Args>
constexpr CONDITIONALLY_EXPLICIT variant (std::in_place_index_t< IDX > inplace, Args &&... args)
 Index emplacement constructor. More...
 
template<size_t IDX, typename U , typename... Args>
constexpr variant (std::in_place_index_t< IDX > inplace, std::initializer_list< U > init, Args &&... args)
 Index emplacement constructor with std::initializer_list More...
 
template<typename U , typename... Args>
constexpr CONDITIONALLY_EXPLICIT variant ([[maybe_unused]] std::in_place_type_t< U > inplace, Args &&... args)
 Type emplacement constructor. More...
 
template<typename U , typename V , typename... Args>
constexpr variant ([[maybe_unused]] std::in_place_type_t< U > inplace, std::initializer_list< V > init, Args &&... args)
 Type emplacement constructor with std::initializer_list More...
 
template<typename U >
constexpr CONDITIONALLY_EXPLICIT variant (U &&value)
 Forwarding constructor. More...
 
template<typename U >
constexpr CONDITIONALLY_EXPLICIT variant (std::initializer_list< U > init)
 Forwarding constructor with initializer list. More...
 
constexpr ~variant () CONDITIONALLY_NOEXCEPT
 Destructor. More...
 
constexpr variantoperator= (const variant &rhs)
 Copy assignment operator. More...
 
constexpr variantoperator= (variant &&rhs)
 Move assignment operator. More...
 
template<typename U >
constexpr variantoperator= (U &&rhs)
 Forwarding assignment operator. More...
 
template<typename U >
constexpr variantoperator= (std::initializer_list< U > rhs)
 Forwarding assignment operator with initializer list. More...
 
constexpr size_t index () const noexcept
 Gets the index of the contained alternative. More...
 
template<size_t I, typename... Args>
constexpr REFERENCE emplace (Args &&... args)
 Constructs a new alternative in place by index. More...
 
template<size_t I, typename U , typename... Args>
constexpr REFERENCE emplace (std::initializer_list< U > ilist, Args &&... args)
 Constructs a new alternative in place by index. More...
 
template<typename U , typename... Args>
constexpr REFERENCE emplace (Args &&... args)
 Constructs a new alternative in place by type. More...
 
template<typename U , typename V , typename... Args>
constexpr REFERENCE emplace (std::initializer_list< V > ilist, Args &&... args)
 Constructs a new alternative in place by type. More...
 
template<size_t I>
constexpr REFERENCE operator[] ([[maybe_unused]] index_t< I > index) &noexcept
 Alternative access operator by index. More...
 
template<size_t I>
constexpr CONST_REFERENCE operator[] ([[maybe_unused]] index_t< I > index) const &noexcept
 Alternative access operator by index. More...
 
template<size_t I>
constexpr RVALUE_REFERENCE operator[] ([[maybe_unused]] index_t< I > index) &&
 Alternative access operator by index. More...
 
template<size_t I>
constexpr CONST_RVALUE_REFERENCE operator[] ([[maybe_unused]] index_t< I > index) const &&
 Alternative access operator by index. More...
 
template<typename U >
constexpr REFERENCE operator[] ([[maybe_unused]] type_t< U > type) &noexcept
 Alternative access operator by type. More...
 
template<typename U >
constexpr CONST_REFERENCE operator[] ([[maybe_unused]] type_t< U > type) const &noexcept
 Alternative access operator by type. More...
 
template<typename U >
constexpr RVALUE_REFERENCE operator[] ([[maybe_unused]] type_t< U > type) &&
 Alternative access operator by type. More...
 
template<typename U >
constexpr CONST_RVALUE_REFERENCE operator[] ([[maybe_unused]] type_t< U > type) const &&
 Alternative access operator by type. More...
 
template<size_t I>
constexpr REFERENCE get () &
 Gets an alternative by index. More...
 
template<size_t I>
constexpr CONST_REFERENCE get () const &
 Gets an alternative by index. More...
 
template<size_t I>
constexpr RVALUE_REFERENCE get () &&
 Gets an alternative by index. More...
 
template<size_t I>
constexpr CONST_RVALUE_REFERENCE get () const &&
 Gets an alternative by index. More...
 
template<typename U >
constexpr REFERENCE get () &
 Gets an alternative by type. More...
 
template<typename U >
constexpr CONST_REFERENCE get () const &
 Gets an alternative by type. More...
 
template<typename U >
constexpr RVALUE_REFERENCE get () &&
 Gets an alternative by type. More...
 
template<typename U >
constexpr CONST_RVALUE_REFERENCE get () const &&
 Gets an alternative by type. More...
 
template<size_t I>
constexpr POINTER get_if () noexcept
 Gets an alternative pointer by index if the variant holds it. More...
 
template<size_t I>
constexpr CONST_POINTER get_if () const noexcept
 Gets an alternative pointer by index if the variant holds it. More...
 
template<typename U >
constexpr POINTER get_if () noexcept
 Gets an alternative pointer by type if the variant holds it. More...
 
template<typename U >
constexpr CONST_POINTER get_if () const noexcept
 Gets an alternative pointer by type if the variant holds it. More...
 
template<typename U >
constexpr bool holds_alternative () const noexcept
 Checks if a variant contains a particular alternative. More...
 
template<typename V >
constexpr DEDUCED visit (V &&visitor) &
 Calls a visitor callable with the contained alternative. More...
 
template<typename V >
constexpr DEDUCED visit (V &&visitor) const &
 Calls a visitor callable with the contained alternative. More...
 
template<typename V >
constexpr DEDUCED visit (V &&visitor) &&
 Calls a visitor callable with the contained alternative. More...
 
template<typename V >
constexpr DEDUCED visit (V &&visitor) const &&
 Calls a visitor callable with the contained alternative. More...
 
template<typename V >
constexpr DEDUCED visit_informed (V &&visitor) &
 Calls a visitor callable with the contained alternative and metadata. More...
 
template<typename V >
constexpr DEDUCED visit_informed (V &&visitor) const &
 Calls a visitor callable with the contained alternative and metadata. More...
 
template<typename V >
constexpr DEDUCED visit_informed (V &&visitor) &&
 Calls a visitor callable with the contained alternative and metadata. More...
 
template<typename V >
constexpr DEDUCED visit_informed (V &&visitor) const &&
 Calls a visitor callable with the contained alternative and metadata. More...
 
constexpr void swap (variant &other) CONDITIONALLY_NOEXCEPT
 Swaps two variant instances. More...
 

Friends

class error_set< T... >
 
template<typename , typename >
class result
 

Related Functions

(Note that these are not member functions.)

template<typename T , typename... U>
constexpr bool holds_alternative (const variant< U... > &v) noexcept
 Checks if a variant contains a particular alternative. More...
 
template<size_t I, typename... T>
constexpr REFERENCE get (variant< T... > &v)
 Gets a variant alternative by index. More...
 
template<size_t I, typename... T>
constexpr CONST_REFERENCE get (const variant< T... > &v)
 Gets a variant alternative by index. More...
 
template<size_t I, typename... T>
constexpr RVALUE_REFERENCE get (variant< T... > &&v)
 Gets a variant alternative by index. More...
 
template<size_t I, typename... T>
constexpr CONST_RVALUE_REFERENCE get (const variant< T... > &&v)
 Gets a variant alternative by index. More...
 
template<typename T , typename... U>
constexpr REFERENCE get (variant< U... > &v)
 Gets a variant alternative by type. More...
 
template<typename T , typename... U>
constexpr CONST_REFERENCE get (const variant< U... > &v)
 Gets a variant alternative by type. More...
 
template<typename T , typename... U>
constexpr RVALUE_REFERENCE get (variant< U... > &&v)
 Gets a variant alternative by type. More...
 
template<typename T , typename... U>
constexpr CONST_RVALUE_REFERENCE get (const variant< U... > &&v)
 Gets a variant alternative by type. More...
 
template<size_t I, typename... T>
constexpr POINTER get_if (variant< T... > &v) noexcept
 Gets a variant alternative pointer by index if the variant holds it. More...
 
template<size_t I, typename... T>
constexpr CONST_POINTER get_if (const variant< T... > &v) noexcept
 Gets a variant alternative pointer by index if the variant holds it. More...
 
template<typename T , typename... U>
constexpr POINTER get_if (variant< U... > &v) noexcept
 Gets a variant alternative pointer by type if the variant holds it. More...
 
template<typename T , typename... U>
constexpr CONST_POINTER get_if (const variant< U... > &v) noexcept
 Gets a variant alternative pointer by type if the variant holds it. More...
 
template<typename V >
constexpr DEDUCED visit (V &&visitor)
 Calls a visitor callable with the contained variant alternatives. More...
 
template<typename V , typename T0 , typename... TN>
constexpr DEDUCED visit (V &&visitor, T0 &&var0, TN &&... varn)
 Calls a visitor callable with the contained variant alternatives. More...
 
template<typename... T>
constexpr void swap (variant< T... > &a, variant< T... > &b) CONDITIONALLY_NOEXCEPT
 Swaps two variant instances. More...
 

Detailed Description

template<typename... T>
class sumty::variant< T >

General discriminated union.

variant is the fundamental sum type of sumty. option, result, and error_set are defined in terms of variant.

variant is very similar to std::variant, but it does have some key differences. Most notably, variant does not support type-based alternative selection unless all alternatives have a distinct type. For example, std::variant will allow the code shown below, but variant will not.

std::variant<int, int> v = 42;

Any such functionality from std::variant that is similarly ambiguous to the reader is disallowed by variant. Otherwise, the interface provided by variant is identical to std::variant, but with some additional functions available.

Another key difference from std::variant is that variant allows alternatives to have void and references (both lvalue and rvalue) as types. When using an lvalue reference as an alternative type, copy and move semantics applied to the variant are the same as a raw pointer (both trivial), instead of immovability of lvalue references.

A more subtle, but important, difference from std::variant is that variant makes size optimizations for several special cases. These special cases revolve around alternatives with types that are lvalue references, void, and empty types (such as std::monostate).

void and empty types need not occupy any memory at runtime, despite the fact that sizeof(<empty-type>) == 1 in C++. A variant consisting entirely of alternatives with types that are void or empty types only takes up enough space to store a discriminant, which is always the smallest possible integral type necessary to store the value N - 1, where N is the number of alternatives. Here are some examples:

struct empty_t {};
assert(std::is_empty_v<variant<void>>);
assert(std::is_empty_v<variant<empty_t>>);
assert(sizeof(variant<void, empty_t>) == sizeof(bool));
assert(sizeof(variant<empty_t, ...>) // repeated 256 times
== sizeof(uint8_t));
assert(sizeof(variant<empty_t, ...>) // repeated 257 times
== sizeof(uint16_t));

lvalue references have the invariant that the underlying pointer is not null. This means in cases where there are only two alternatives, with one being an lvalue reference and the other being void or an empty type, null and non-null can be used as the discriminanting values instead of having a separate discriminant. Here are some more examples:

struct empty_t {};
assert(sizeof(variant<int&, void>) == sizeof(int*));
assert(sizeof(variant<empty_t, int&>) == sizeof(int*));
Template Parameters
Tvariant alternative types

Constructor & Destructor Documentation

◆ variant() [1/9]

constexpr variant ( )
constexpr

Default constructor.

Initializes the variant such that it contains a default constructed value of the first (index 0) alternative.

The first alternative must be default constructible for this constructor to participate in overload resoltuion, but no other alternatives need be default constructible.

Example

variant<int, bool, int> v;
assert(holds_alternative<int>(v));
assert(v.index() == 0);
assert(get<0>(v) == int{});

◆ variant() [2/9]

constexpr variant ( const variant< T > &  )
constexpr

Copy constructor.

A new variant is initialized such that it contains a copy constructed instance of the alternative contained in the source variant. If the source variant has more than one alternative of the same type, the new variant will contain the alternative of the same index.

All alternative types must be copy constructible for this constructor to participate in overload resolution.

Example

variant<int, bool, int> v1{std::in_place_index<2>, 42};
variant<int, bool, int> v2{v1};
assert(holds_alternative<int>(v2));
assert(v2.index() == 2);
assert(get<2>(v2) == 42);

◆ variant() [3/9]

constexpr variant ( variant< T > &&  )
constexpr

Move constructor.

A new variant is initialized such that it contains a move constructed instance of the alternative contained in the source variant. If the source vairant has more than one alternative of the same type, the new variant will contain the alternative of the same index.

All alternative types must be move constructible for this constructor to participate in overload resolution.

The source variant will continue to contain an instance of the same alternative, but the value of the alternative after being moved depends on the move constructor of the type. In general, moved values are said to be in a valid, but unspecified, state.

Example

variant<int, bool, int> v1{std::in_place_index<2>, 42};
variant<int, bool, int> v2{std::move(v1)};
assert(holds_alternative<int>(v2));
assert(v2.index() == 2);
assert(get<2>(v2) == 42);

◆ variant() [4/9]

constexpr CONDITIONALLY_EXPLICIT variant ( std::in_place_index_t< IDX >  inplace,
Args &&...  args 
)
inlineconstexpr

Index emplacement constructor.

A new variant is initialized such that it contains a newly constructed instance of the alternative with the specified index. The arguments following inplace are forwarded directly to the constructor of the alternative type.

Given that U is the type of the alternative at the specified index, this constructor is always valid as long as U is constructible with the arguments, std::forward<Args>(args)....

Example

variant<int, std::string> v{std::in_place_index<1>, 5, 'a'};
assert(holds_alternative<std::string>(v));
assert(v.index() == 1);
assert(get<1>(v) == "aaaaa");
Parameters
inplaceConstructor tag that specifies the alternative index.
argsArguments used to construct the alternative.

◆ variant() [5/9]

constexpr variant ( std::in_place_index_t< IDX >  inplace,
std::initializer_list< U >  init,
Args &&...  args 
)
inlineconstexpr

Index emplacement constructor with std::initializer_list

A new variant is initialized such that it contains a newly constructed instance of the alternative with the specified index. The arguments following inplace are forwarded directly to the constructor of the alternative type.

Given that U is the type of the alternative at the specified index, this constructor is always valid as long as U is constructible with the arguments, init, std::forward<Args>(args)....

Example

variant<int, std::vector<int>> v{
std::in_place_index<1>,
{1, 2, 3, 4, 5}};
assert(holds_alternative<std::vector<int>>(v));
assert(v.index() == 1);
assert(get<1>(v).size() == 5);
constexpr bool holds_alternative() const noexcept
Checks if a variant contains a particular alternative.
Definition: variant.hpp:1819
Parameters
inplaceConstructor tag that specifies the alternative index.
initInitializer list forwarded to the alternative constructor
argsAdditional arguments used to construct the alternative.

◆ variant() [6/9]

constexpr CONDITIONALLY_EXPLICIT variant ( [[maybe_unused] ] std::in_place_type_t< U >  inplace,
Args &&...  args 
)
inlineconstexpr

Type emplacement constructor.

A new variant is initialized such that it contains a newly constructed instance of the alternative with the specified type. The arguments following inplace are forwarded directory to the constructor of the alternative type.

This constructor only participates in overload resolution if the alternative type, U, is unique among all alternatives of the variant. That is, variant<A, B, A>, cannot use this constructor to initialize an alternative of type A, but it could use this constructor to initialize the alternative of type B. This constraint is imposed to prevent ambiguity to the reader. Use the index based emplacement constructor instead to initialize the alternative of type A.

Example

variant<int, std::string> v{
std::in_place_type<std::string>,
5, 'a'};
assert(holds_alternative<std::string>(v));
assert(v.index() == 1);
assert(get<1>(v) == "aaaaa");

◆ variant() [7/9]

constexpr variant ( [[maybe_unused] ] std::in_place_type_t< U >  inplace,
std::initializer_list< V >  init,
Args &&...  args 
)
inlineconstexpr

Type emplacement constructor with std::initializer_list

A new variant is initialized such that it contains a newly constructed instance of the alternative with the specified type. The arguments following inplace are forwarded directory to the constructor of the alternative type.

This constructor only participates in overload resolution if the alternative type, U, is unique among all alternatives of the variant. That is, variant<A, B, A>, cannot use this constructor to initialize an alternative of type A, but it could use this constructor to initialize the alternative of type B. This constraint is imposed to prevent ambiguity to the reader. Use the index based emplacement constructor instead to initialize the alternative of type A.

Example

variant<int, std::vector<int>> v{
std::in_place_type<std::vector<int>>,
{1, 2, 3, 4, 5}};
assert(holds_alternative<std::vector<int>>(v));
assert(v.index() == 1);
assert(get<1>(v).size() == 5);

◆ variant() [8/9]

constexpr CONDITIONALLY_EXPLICIT variant ( U &&  value)
inlineconstexpr

Forwarding constructor.

A new variant is initialized such that an alternative is constructed in place with the provided value as the constructor argument.

To avoid ambiguity to the reader, this constructor only participates in overload resolution when there is only one alternative that could possibly be constructed from the value.

This constructor is explicit if the value is not implicitly convertible to the target alternative type.

This constructor should be avoided in generic code, because some variant instantiations will have distinct types while others will not. Prefer the emplacement constructors.

Example

variant<void, int> v{42};
assert(v.index() == 1);
assert(get<1>(v) == 42);
Parameters
valueThe value that is used to construct the alternative

◆ variant() [9/9]

constexpr CONDITIONALLY_EXPLICIT variant ( std::initializer_list< U >  init)
inlineconstexpr

Forwarding constructor with initializer list.

A new variant is initialized such that an alternative is constructed in place with the provided std::initializer_list as the constructor argument.

To avoid ambiguity to the reader, this constructor only participates in overload resulotion when there is only one alternative that could possible be constructed from the initializer list.

This constructor is explicit if the std::initializer_list is not implicitly convertible to the target alternative type.

This constructor should be avoided in generic code, because some variant instantiations will have distinct types while others will not. Prefer the emplacement constructors.

Example

variant<void, std::vector<int>> v({1, 2, 3, 4, 5});
assert(v.index() == 1);
assert(get<1>(v).size() == 5);
Parameters
initThe std::initializer_list that is used to construct the alternative

◆ ~variant()

constexpr ~variant ( )
constexpr

Destructor.

The contained alternative of the variant will is destroyed in place.

The destructor is noexcept if all alternative types are nothrow destructible.

Member Function Documentation

◆ emplace() [1/4]

constexpr REFERENCE emplace ( Args &&...  args)
inlineconstexpr

Constructs a new alternative in place by index.

This function destroys the alternative that the variant contains before the call, and constructs a new alternative with the specified index in place.

Example

variant<int, std::string> v;
v.emplace<1>(5, 'a');
assert(holds_alternative<std::string>(v));
assert(v.index() == 1);
assert(get<1>(v) == "aaaaa");
Parameters
argsConstructor arguments forwarded to the new alternative
Returns
A reference to the new alternative, if applicable

◆ emplace() [2/4]

constexpr REFERENCE emplace ( Args &&...  args)
inlineconstexpr

Constructs a new alternative in place by type.

This function destroy the alternative that the variant contains before the call, and constructs a new alternative with the specified type in place.

This function only participates in overload resolution if the type, U, is unique among all the alternative types of the variant. That is, variant<A, B, A> cannot use this function to emplace an alternative of type A, but it can use this function to emplace an alternative of type B.

Example

variant<int, std::string> v;
v.emplace<std::string>(5, 'a');
assert(holds_alternative<std::string>(v));
assert(v.index() == 1);
assert(get<1>(v) == "aaaaa");
Parameters
argsConstructor arguments forwarded to the new alternative
Returns
A reference to the new alternative, if applicable

◆ emplace() [3/4]

constexpr REFERENCE emplace ( std::initializer_list< U >  ilist,
Args &&...  args 
)
inlineconstexpr

Constructs a new alternative in place by index.

This function destroys the alternative that the variant contains before the call, and constructs a new alternative with the specified index in place.

Example

variant<int, std::vector<int>> v;
v.emplace<1>({1, 2, 3, 4, 5});
assert(holds_alternative<std::vector<int>>(v));
assert(v.index() == 1);
assert(get<1>(v).size() == 5);
Parameters
ilistInitializer list forward to the new alternative
argsConstructor arguments forwarded to the new alternative
Returns
A reference to the new alternative, if applicable

◆ emplace() [4/4]

constexpr REFERENCE emplace ( std::initializer_list< V >  ilist,
Args &&...  args 
)
inlineconstexpr

Constructs a new alternative in place by type.

This function destroy the alternative that the variant contains before the call, and constructs a new alternative with the specified type in place.

This function only participates in overload resolution if the type, U, is unique among all the alternative types of the variant. That is, variant<A, B, A> cannot use this function to emplace an alternative of type A, but it can use this function to emplace an alternative of type B.

Example

variant<int, std::vector<int>> v;
v.emplace<std::vector<int>>({1, 2, 3, 4, 5});
assert(holds_alternative<std::vector<int>>(v));
assert(v.index() == 1);
assert(get<1>(v).size() == 5);
Parameters
ilistInitializer list forward to the new alternative
argsConstructor arguments forwarded to the new alternative
Returns
A reference to the new alternative, if applicable

◆ get() [1/8]

constexpr REFERENCE get ( ) &
inlineconstexpr

Gets an alternative by index.

This function allows accessing alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<1>() == 42);
v.get<1>() = 24;
assert(get<int>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [2/8]

constexpr REFERENCE get ( ) &
inlineconstexpr

Gets an alternative by type.

This function allows accessing alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<int>() == 42);
v.get<int>() = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [3/8]

constexpr RVALUE_REFERENCE get ( ) &&
inlineconstexpr

Gets an alternative by index.

This function allows accessing alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<1>() == 42);
v.get<1>() = 24;
assert(get<int>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [4/8]

constexpr RVALUE_REFERENCE get ( ) &&
inlineconstexpr

Gets an alternative by type.

This function allows accessing alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<int>() == 42);
v.get<int>() = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [5/8]

constexpr CONST_REFERENCE get ( ) const &
inlineconstexpr

Gets an alternative by index.

This function allows accessing alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<1>() == 42);
v.get<1>() = 24;
assert(get<int>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [6/8]

constexpr CONST_REFERENCE get ( ) const &
inlineconstexpr

Gets an alternative by type.

This function allows accessing alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<int>() == 42);
v.get<int>() = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [7/8]

constexpr CONST_RVALUE_REFERENCE get ( ) const &&
inlineconstexpr

Gets an alternative by index.

This function allows accessing alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<1>() == 42);
v.get<1>() = 24;
assert(get<int>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [8/8]

constexpr CONST_RVALUE_REFERENCE get ( ) const &&
inlineconstexpr

Gets an alternative by type.

This function allows accessing alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v.get<int>() == 42);
v.get<int>() = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get_if() [1/4]

constexpr CONST_POINTER get_if ( ) const
inlineconstexprnoexcept

Gets an alternative pointer by index if the variant holds it.

This functions tries to access an alternative by index. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*v.get_if<1>() == 42);
*v.get_if<1>() = 24;
assert(*v.get_if<1>() == 24);
assert(v.get_if<0>() == nullptr);
Template Parameters
IThe index of the alternative to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [2/4]

constexpr CONST_POINTER get_if ( ) const
inlineconstexprnoexcept

Gets an alternative pointer by type if the variant holds it.

This functions tries to access an alternative by type. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*v.get_if<int>() == 42);
*v.get_if<int>() = 24;
assert(*v.get_if<int>() == 24);
assert(v.get_if<bool>() == nullptr);
Template Parameters
IThe index of the alternative to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [3/4]

constexpr POINTER get_if ( )
inlineconstexprnoexcept

Gets an alternative pointer by index if the variant holds it.

This functions tries to access an alternative by index. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*v.get_if<1>() == 42);
*v.get_if<1>() = 24;
assert(*v.get_if<1>() == 24);
assert(v.get_if<0>() == nullptr);
Template Parameters
IThe index of the alternative to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [4/4]

constexpr POINTER get_if ( )
inlineconstexprnoexcept

Gets an alternative pointer by type if the variant holds it.

This functions tries to access an alternative by type. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*v.get_if<int>() == 42);
*v.get_if<int>() = 24;
assert(*v.get_if<int>() == 24);
assert(v.get_if<bool>() == nullptr);
Template Parameters
IThe index of the alternative to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ holds_alternative()

constexpr bool holds_alternative ( ) const
inlineconstexprnoexcept

Checks if a variant contains a particular alternative.

Given a type parameter, this function checks if the variant currently holds an alternative that has the exact same type.

Example

variant<int, bool, int> v1{std::in_place_index<0>, 42};
assert(v1.holds_alternative<int>());
variant<int, bool, int> v2{std::in_place_index<2>, 42};
assert(v2.holds_alternative<int>());
Returns
true if the variant holds an alternative of the given type.

◆ index()

constexpr size_t index ( ) const
inlineconstexprnoexcept

Gets the index of the contained alternative.

The set of alternatives of a variant has a zero-based index based on the order in which they are specified in the variant template arguments.

This index is the normalized discriminant of the variant. The discriminant may be represented differently internally, depending on the alternative types, so this function normalizes the discriminant by converting it to a zero-based index in order to provide a common interface for all variant instantiations.

Example

variant<int, bool, float&, std::string, void> v{
std::in_place_index<3>, "hello"};
assert(v.index() == 3);
Returns
The index of the contained alternative.

◆ operator=() [1/4]

constexpr variant& operator= ( const variant< T > &  rhs)
constexpr

Copy assignment operator.

Copy assignment of a variant can take one of two possible code paths.

If the source and destination variant hold the same alternative (same index), the alternative value is copied via copy assignment.

Otherwise, if the source and destination hold different alternatives (different indices, but possibly the same type), the alternative of the destination variant is destroyed in place, and the new alternative is copy constructed.

All alternatives must be both copy assignable and copy constructible for this function to participate in overload resolution.

Example

variant<int, bool> v1{std::in_place_index<0>, 42};
variant<int, bool> v2{std::in_place_index<1>, true};
v1 = v2;
assert(holds_alternative<bool>(v1));
assert(v1.index() == 1);
assert(get<1>(v1) == true);

◆ operator=() [2/4]

constexpr variant& operator= ( std::initializer_list< U >  rhs)
inlineconstexpr

Forwarding assignment operator with initializer list.

This function assigns a std::initializer_list directoy to an alternative. If the variant already contains the target alternative, the std::initializer_list is assigned uting the alternative type's assignment operator. Otherwise, the target alternative is constructed with the std::initializer_list.

To avoid ambiguity to the reader, this function only participates in overload resolution when there is only one alternative that could possibly be assigned from the std::initializer_list.

This opreator should be avoided in generic code, because some variant instantiations will have distinct types while others will not.

Example

variant<void, std::vector<int>> v{};
v = {1, 2, 3, 4, 5};
assert(v.index() == 1);
assert(get<1>(v).size() == 5);
Parameters
rhsThe std::initializer_list to be assigned to the alternative

◆ operator=() [3/4]

constexpr variant& operator= ( U &&  rhs)
inlineconstexpr

Forwarding assignment operator.

This function assigns a value directly to an alternative. If the variant already contains the target alternative, the value is assigned using the alternative type's assignemnt operator. Otherwise, the target alternative is constructed with the value.

To avoid ambiguity to the reader, this function only participates in overload resolution when there is only one alternative that could possibly be assigned from the value.

This operator should be avoided in generic code, because some variant instantiations will have distinct types while others will not.

Example

variant<void, int> v{};
v = 42;
assert(v.index() == 1);
assert(get<1>(v) == 42);
Parameters
rhsThe value to be assigned to the alternative

◆ operator=() [4/4]

constexpr variant& operator= ( variant< T > &&  rhs)
constexpr

Move assignment operator.

Move assignment of a variant can take one of two possible code paths.

If the source and destination variant hold the same alternative (same index), the alternative value is moved from the source to the destination via move assignment.

Otherwise, if the source and destination hold different alternatives (different indices, but possibly the same type), the alternative of the destination variant is destroyed in place, and the new alternative is move constructed.

The source variant will still contain the same alternative, but the value of the alternative depends on the move assignment or move constructor of the alternative's type. In general, moved values are said to be in a valid, but unspecified, state.

All alternatives must be both move assignable and move constructible for this function to participate in overload resolution.

Example

variant<int, bool> v1{std::in_place_index<0>, 42};
variant<int, bool> v2{std::in_place_index<1>, true};
v1 = std::move(v2);
assert(holds_alternative<bool>(v1));
assert(v1.index() == 1);
assert(get<1>(v1) == true);

◆ operator[]() [1/8]

constexpr RVALUE_REFERENCE operator[] ( [[maybe_unused] ] index_t< I >  index) &&
inlineconstexpr

Alternative access operator by index.

This function allows accessing alternatives by index using the square bracket operator. Because the index must be a compile time value, instead of passing the index directly, the index is provided as an instance of index_t.

This operator is unchecked and does not throw an exception. Passing an index that does not correspond to the currently contained alternative results in undefined behavior.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v[index<1>] == 42);
v[index<1>] = 24;
assert(get<1>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
The accessed alternative value, if applicable

◆ operator[]() [2/8]

constexpr REFERENCE operator[] ( [[maybe_unused] ] index_t< I >  index) &
inlineconstexprnoexcept

Alternative access operator by index.

This function allows accessing alternatives by index using the square bracket operator. Because the index must be a compile time value, instead of passing the index directly, the index is provided as an instance of index_t.

This operator is unchecked and does not throw an exception. Passing an index that does not correspond to the currently contained alternative results in undefined behavior.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v[index<1>] == 42);
v[index<1>] = 24;
assert(get<1>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
A reference to the accessed alternative, if applicable

◆ operator[]() [3/8]

constexpr CONST_RVALUE_REFERENCE operator[] ( [[maybe_unused] ] index_t< I >  index) const &&
inlineconstexpr

Alternative access operator by index.

This function allows accessing alternatives by index using the square bracket operator. Because the index must be a compile time value, instead of passing the index directly, the index is provided as an instance of index_t.

This operator is unchecked and does not throw an exception. Passing an index that does not correspond to the currently contained alternative results in undefined behavior.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v[index<1>] == 42);
v[index<1>] = 24;
assert(get<1>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
The accessed alternative value, if applicable

◆ operator[]() [4/8]

constexpr CONST_REFERENCE operator[] ( [[maybe_unused] ] index_t< I >  index) const &
inlineconstexprnoexcept

Alternative access operator by index.

This function allows accessing alternatives by index using the square bracket operator. Because the index must be a compile time value, instead of passing the index directly, the index is provided as an instance of index_t.

This operator is unchecked and does not throw an exception. Passing an index that does not correspond to the currently contained alternative results in undefined behavior.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(v[index<1>] == 42);
v[index<1>] = 24;
assert(get<1>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
A reference to the accessed alternative, if applicable

◆ operator[]() [5/8]

constexpr RVALUE_REFERENCE operator[] ( [[maybe_unused] ] type_t< U >  type) &&
inlineconstexpr

Alternative access operator by type.

This function allows accessing alternatives by type using the square bracket operator. Because the type must be a compile time value, the type is provided as an instance of type_t.

This operator is unchecked and does not throw an exception. Passing a type that does not correspond to the currently contained alternative results in undefined behavior.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_type<int>, 42};
assert(v[type<int>] == 42);
v[type<int>] = 24;
assert(get<int>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
The accessed alternative value, if applicable

◆ operator[]() [6/8]

constexpr REFERENCE operator[] ( [[maybe_unused] ] type_t< U >  type) &
inlineconstexprnoexcept

Alternative access operator by type.

This function allows accessing alternatives by type using the square bracket operator. Because the type must be a compile time value, the type is provided as an instance of type_t.

This operator is unchecked and does not throw an exception. Passing a type that does not correspond to the currently contained alternative results in undefined behavior.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_type<int>, 42};
assert(v[type<int>] == 42);
v[type<int>] = 24;
assert(get<int>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
A reference to the accessed alternative, if applicable

◆ operator[]() [7/8]

constexpr CONST_RVALUE_REFERENCE operator[] ( [[maybe_unused] ] type_t< U >  type) const &&
inlineconstexpr

Alternative access operator by type.

This function allows accessing alternatives by type using the square bracket operator. Because the type must be a compile time value, the type is provided as an instance of type_t.

This operator is unchecked and does not throw an exception. Passing a type that does not correspond to the currently contained alternative results in undefined behavior.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_type<int>, 42};
assert(v[type<int>] == 42);
v[type<int>] = 24;
assert(get<int>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
The accessed alternative value, if applicable

◆ operator[]() [8/8]

constexpr CONST_REFERENCE operator[] ( [[maybe_unused] ] type_t< U >  type) const &
inlineconstexprnoexcept

Alternative access operator by type.

This function allows accessing alternatives by type using the square bracket operator. Because the type must be a compile time value, the type is provided as an instance of type_t.

This operator is unchecked and does not throw an exception. Passing a type that does not correspond to the currently contained alternative results in undefined behavior.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_type<int>, 42};
assert(v[type<int>] == 42);
v[type<int>] = 24;
assert(get<int>(v) == 24);
Parameters
indexA tag value that communicates a compile time index
Returns
A reference to the accessed alternative, if applicable

◆ swap()

constexpr void swap ( variant< T > &  other)
inlineconstexpr

Swaps two variant instances.

If the two variant instances contain the same alternative, the alternative values are swapped directly. Otherwise, the alternatives are swapped by moving out of the variants, destroying the old alternatives, and move constructed into the new alternatives.

Example

variant<bool, int, void> v1{std::in_place_index<0>, true};
variant<bool, int, void> v2{std::in_place_index<1>, 42};
v1.swap(v2);
assert(v1.index() == 1);
assert(get<1>(v1) == 42);
assert(v2.index() == 0);
assert(get<2>(v2) == true);
Parameters
otherThe "other" variant to swap with this variant

◆ visit() [1/4]

constexpr DEDUCED visit ( V &&  visitor) &
inlineconstexpr

Calls a visitor callable with the contained alternative.

This function calls the visitor as std::invoke(visitor, alternative) and returns the result of that call, if any. As such, visitor must be able to accecpt any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v).

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit(overload(
[](bool bool_value) { assert(false); },
[](int int_value) { assert(int_value == 42); },
[](void_t void_value) { assert(false); }
));
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit() [2/4]

constexpr DEDUCED visit ( V &&  visitor) &&
inlineconstexpr

Calls a visitor callable with the contained alternative.

This function calls the visitor as std::invoke(visitor, alternative) and returns the result of that call, if any. As such, visitor must be able to accecpt any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v).

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit(overload(
[](bool bool_value) { assert(false); },
[](int int_value) { assert(int_value == 42); },
[](void_t void_value) { assert(false); }
));
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit() [3/4]

constexpr DEDUCED visit ( V &&  visitor) const &
inlineconstexpr

Calls a visitor callable with the contained alternative.

This function calls the visitor as std::invoke(visitor, alternative) and returns the result of that call, if any. As such, visitor must be able to accecpt any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v).

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit(overload(
[](bool bool_value) { assert(false); },
[](int int_value) { assert(int_value == 42); },
[](void_t void_value) { assert(false); }
));
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit() [4/4]

constexpr DEDUCED visit ( V &&  visitor) const &&
inlineconstexpr

Calls a visitor callable with the contained alternative.

This function calls the visitor as std::invoke(visitor, alternative) and returns the result of that call, if any. As such, visitor must be able to accecpt any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v).

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit(overload(
[](bool bool_value) { assert(false); },
[](int int_value) { assert(int_value == 42); },
[](void_t void_value) { assert(false); }
));
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit_informed() [1/4]

constexpr DEDUCED visit_informed ( V &&  visitor) &
inlineconstexpr

Calls a visitor callable with the contained alternative and metadata.

This function calls the visitor as std::invoke(visitor, alternative, info), and returns the result of that call, if any. As such, visitor must be able to accept any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v, info).

The info argument passed to the visitor, which differentiates this function from .visit(...), communicates constexpr information about the alternative being visited. The type of the info object is not meant to be named, but it has the API shown below. Note that info is always an empty type.

struct alternative_info {
// index of the alternative in the source variant
static inline constexpr size_t index = ...;
// type of the alternative as declared in the source variant
using type = ...;
};
constexpr size_t index() const noexcept
Gets the index of the contained alternative.
Definition: variant.hpp:825

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit_informed([](auto value, auto info) {
if constexpr (info.index == 0) {
assert(false);
} else if constexpr (info.index == 1) {
assert(value == 42);
} else if constexpr (info.index == 2) {
assert(false);
}
});
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit_informed() [2/4]

constexpr DEDUCED visit_informed ( V &&  visitor) &&
inlineconstexpr

Calls a visitor callable with the contained alternative and metadata.

This function calls the visitor as std::invoke(visitor, alternative, info), and returns the result of that call, if any. As such, visitor must be able to accept any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v, info).

The info argument passed to the visitor, which differentiates this function from .visit(...), communicates constexpr information about the alternative being visited. The type of the info object is not meant to be named, but it has the API shown below. Note that info is always an empty type.

struct alternative_info {
// index of the alternative in the source variant
static inline constexpr size_t index = ...;
// type of the alternative as declared in the source variant
using type = ...;
};

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
std::move(v1).visit_informed([](auto value, auto info) {
if constexpr (info.index == 0) {
assert(false);
} else if constexpr (info.index == 1) {
assert(value == 42);
} else if constexpr (info.index == 2) {
assert(false);
}
});
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit_informed() [3/4]

constexpr DEDUCED visit_informed ( V &&  visitor) const &
inlineconstexpr

Calls a visitor callable with the contained alternative and metadata.

This function calls the visitor as std::invoke(visitor, alternative, info), and returns the result of that call, if any. As such, visitor must be able to accept any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v, info).

The info argument passed to the visitor, which differentiates this function from .visit(...), communicates constexpr information about the alternative being visited. The type of the info object is not meant to be named, but it has the API shown below. Note that info is always an empty type.

struct alternative_info {
// index of the alternative in the source variant
static inline constexpr size_t index = ...;
// type of the alternative as declared in the source variant
using type = ...;
};

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

const variant<bool, int, void> v1{std::in_place_index<1>, 42};
v1.visit_informed([](auto value, auto info) {
if constexpr (info.index == 0) {
assert(false);
} else if constexpr (info.index == 1) {
assert(value == 42);
} else if constexpr (info.index == 2) {
assert(false);
}
});
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit_informed() [4/4]

constexpr DEDUCED visit_informed ( V &&  visitor) const &&
inlineconstexpr

Calls a visitor callable with the contained alternative and metadata.

This function calls the visitor as std::invoke(visitor, alternative, info), and returns the result of that call, if any. As such, visitor must be able to accept any alternative type as an argument. In the case of an alternative of type void, the visitor must be callable as std::invoke(visitor, void_v, info).

The info argument passed to the visitor, which differentiates this function from .visit(...), communicates constexpr information about the alternative being visited. The type of the info object is not meant to be named, but it has the API shown below. Note that info is always an empty type.

struct alternative_info {
// index of the alternative in the source variant
static inline constexpr size_t index = ...;
// type of the alternative as declared in the source variant
using type = ...;
};

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

const variant<bool, int, void> v1{std::in_place_index<1>, 42};
std::move(v1).visit_informed([](auto value, auto info) {
if constexpr (info.index == 0) {
assert(false);
} else if constexpr (info.index == 1) {
assert(value == 42);
} else if constexpr (info.index == 2) {
assert(false);
}
});
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

Friends And Related Function Documentation

◆ get() [1/8]

constexpr CONST_RVALUE_REFERENCE get ( const variant< T... > &&  v)
related

Gets a variant alternative by index.

This function allows accessing variant alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<1>(v) == 42);
get<1>(v) = 24;
assert(get<1>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [2/8]

constexpr CONST_REFERENCE get ( const variant< T... > &  v)
related

Gets a variant alternative by index.

This function allows accessing variant alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<1>(v) == 42);
get<1>(v) = 24;
assert(get<1>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [3/8]

constexpr CONST_RVALUE_REFERENCE get ( const variant< U... > &&  v)
related

Gets a variant alternative by type.

This function allows accessing variant alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<int>(v) == 42);
get<int>(v) = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Parameters
vThe variant to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [4/8]

constexpr CONST_REFERENCE get ( const variant< U... > &  v)
related

Gets a variant alternative by type.

This function allows accessing variant alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<int>(v) == 42);
get<int>(v) = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Parameters
vThe variant to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [5/8]

constexpr RVALUE_REFERENCE get ( variant< T... > &&  v)
related

Gets a variant alternative by index.

This function allows accessing variant alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<1>(v) == 42);
get<1>(v) = 24;
assert(get<1>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [6/8]

constexpr REFERENCE get ( variant< T... > &  v)
related

Gets a variant alternative by index.

This function allows accessing variant alternatives by index, which is provided as a template argument.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<1>(v) == 42);
get<1>(v) = 24;
assert(get<1>(v) == 24);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding index.

◆ get() [7/8]

constexpr RVALUE_REFERENCE get ( variant< U... > &&  v)
related

Gets a variant alternative by type.

This function allows accessing variant alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<int>(v) == 42);
get<int>(v) = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Parameters
vThe variant to access.
Returns
The accessed alternative value, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get() [8/8]

constexpr REFERENCE get ( variant< U... > &  v)
related

Gets a variant alternative by type.

This function allows accessing variant alternatives by type, which is provided as a template argument.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(get<int>(v) == 42);
get<int>(v) = 24;
assert(get<int>(v) == 24);
Template Parameters
UThe type of the alternative to access.
Parameters
vThe variant to access.
Returns
A reference to the accessed alternative, if applicable.
Exceptions
bad_variant_accessThrown if the variant does not contain the alternative with the corresponding type.

◆ get_if() [1/4]

constexpr CONST_POINTER get_if ( const variant< T... > &  v)
related

Gets a variant alternative pointer by index if the variant holds it.

This functions tries to access a variant alternative by index. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*get_if<1>(v) == 42);
*get_if<1>(v) = 24;
assert(*get_if<1>(v) == 24);
assert(get_if<0>(v) == nullptr);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [2/4]

constexpr CONST_POINTER get_if ( const variant< U... > &  v)
related

Gets a variant alternative pointer by type if the variant holds it.

This functions tries to access an alternative by type. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*get_if<int>(v) == 42);
*get_if<int>(v) = 24;
assert(*get_if<int>(v) == 24);
assert(get_if<bool>(v) == nullptr);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [3/4]

constexpr POINTER get_if ( variant< T... > &  v)
related

Gets a variant alternative pointer by index if the variant holds it.

This functions tries to access a variant alternative by index. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*get_if<1>(v) == 42);
*get_if<1>(v) = 24;
assert(*get_if<1>(v) == 24);
assert(get_if<0>(v) == nullptr);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access
Returns
A pointer to the accessed alternative, if applicable, or null

◆ get_if() [4/4]

constexpr POINTER get_if ( variant< U... > &  v)
related

Gets a variant alternative pointer by type if the variant holds it.

This functions tries to access an alternative by type. If the variant contains the alternative, this function returns a pointer to the alternative, if applicable. If the variant does not contain the alternative, this function returns null. In the case where the alternative is of type void, this function does nothing.

This function only participates in overload resolution if the type is unique across all alternative types of the variant. That is, variant<A, B, A> cannot use this function to access an alternative of type A, but it can use this fucntion to access an alternative of type B.

Example

variant<bool, int, void> v{std::in_place_index<1>, 42};
assert(*get_if<int>(v) == 42);
*get_if<int>(v) = 24;
assert(*get_if<int>(v) == 24);
assert(get_if<bool>(v) == nullptr);
Template Parameters
IThe index of the alternative to access.
Parameters
vThe variant to access.
Returns
A pointer to the accessed alternative, if applicable, or null

◆ holds_alternative()

constexpr bool holds_alternative ( const variant< U... > &  v)
related

Checks if a variant contains a particular alternative.

Given a type parameter, this function checks if the variant currently holds an alternative that has the exact same type.

Example

variant<int, bool, int> v1{std::in_place_index<0>, 42};
assert(holds_alternative<int>(v1));
variant<int, bool, int> v2{std::in_place_index<2>, 42};
assert(holds_alternative<int>(v2));
Parameters
vThe variant to check.
Returns
true if the variant holds an alternative of the given type.

◆ swap()

constexpr void swap ( variant< T... > &  a,
variant< T... > &  b 
)
related

Swaps two variant instances.

If the two variant instances contain the same alternative, the alternative values are swapped directly. Otherwise, the alternatives are swapped by moving out of the variants, destroying the old alternatives, and move constructed into the new alternatives.

Example

variant<bool, int, void> v1{std::in_place_index<0>, true};
variant<bool, int, void> v2{std::in_place_index<1>, 42};
swap(v1, v2);
assert(v1.index() == 1);
assert(get<1>(v1) == 42);
assert(v2.index() == 0);
assert(get<2>(v2) == true);
constexpr void swap(variant &other) CONDITIONALLY_NOEXCEPT
Swaps two variant instances.
Definition: variant.hpp:2287
Parameters
aThe first variant in the swap
bThe second variant in the swap

◆ visit() [1/2]

constexpr DEDUCED visit ( V &&  visitor)
related

Calls a visitor callable with the contained variant alternatives.

This function calls the visitor as std::invoke(visitor, alternative...) and returns the result of that call, if any. As such, visitor must be able to accecpt any combination of alternative types as arguments. In the case of an alternative type void, the visitor must accept nothing for that argument. That is, the alternative type combination int, void, int, would result in the visitor being called as std::invoke(visitor, int_value, int_value), essentially skipping the void alternative.

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
variant<float, int> v2{std::in_place_index<0>, 3.14};
visit(overload(
[](bool val1, float val2) { assert(false); },
[](int val1, float val2) { assert(val1 == 42); },
[](float val2) { assert(false); },
[](bool val1, int val2) { assert(false); },
[](int val1, float val2) { assert(false); },
[](int val2) { assert(false); }
), v1, v2);
constexpr DEDUCED visit(V &&visitor) &
Calls a visitor callable with the contained alternative.
Definition: variant.hpp:1866
Parameters
visitorThe callable object that will be passed an alternative.
Returns
The return value of the visitor, if any.

◆ visit() [2/2]

constexpr DEDUCED visit ( V &&  visitor,
T0 &&  var0,
TN &&...  varn 
)
related

Calls a visitor callable with the contained variant alternatives.

This function calls the visitor as std::invoke(visitor, alternative...) and returns the result of that call, if any. As such, visitor must be able to accecpt any combination of alternative types as arguments. In the case of an alternative type void, the visitor must accept nothing for that argument. That is, the alternative type combination int, void, int, would result in the visitor being called as std::invoke(visitor, int_value, int_value), essentially skipping the void alternative.

Note that the overload function can be helpful for defining a visitor inline.

Also note that this function is implemented as a compile-time-defined jump table (array of function pointers). In performance critical applications, be wary of any assumptions about how well or poorly your compiler will optimize a call to this function.

Example

variant<bool, int, void> v1{std::in_place_index<1>, 42};
variant<float, int> v2{std::in_place_index<0>, 3.14};
visit(overload(
[](bool val1, float val2) { assert(false); },
[](int val1, float val2) { assert(val1 == 42); },
[](float val2) { assert(false); },
[](bool val1, int val2) { assert(false); },
[](int val1, float val2) { assert(false); },
[](int val2) { assert(false); }
), v1, v2);
Parameters
visitorThe callable object that will be passed an alternative.
var0The first variant to visit
varnThe remaining variant to visit
Returns
The return value of the visitor, if any.

The documentation for this class was generated from the following files: