Overview
+This library implements a type-safe discriminated union (variant) type,
+variant<T…>
, that almost conforms to the C++17 Standard’s
+std::variant<T…>
. The
+main differences between the two are:
-
+
-
+
+variant<T…>
does not have a valueless-by-exception state;
+ -
+
A converting constructor from, e.g.
+variant<int, float>
to +variant<float, double, int>
is provided as an extension;
+ -
+
The reverse operation, going from
+variant<float, double, int>
to +variant<int, float>
is provided as the member functionsubset<U…>
. +(This operation can throw if the current state of the variant cannot be +represented.)
+ -
+
+variant<T…>
is not trivial when all contained types are trivial, as +mandated by C++17.
+
To avoid the valueless-by-exception state, this implementation falls +back to using double storage unless
+-
+
-
+
one of the alternatives is the type
+monostate
,
+ -
+
one of the alternatives has a nonthrowing default constructor, or
+
+ -
+
all the contained types are nothrow move constructible.
+
+
If the first two bullets don’t hold, but the third does, the variant uses
+single storage, but emplace
constructs a temporary and moves it into place
+if the construction of the object can throw. In case this is undesirable, one
+can force emplace
into always constructing in-place by adding monostate
as
+one of the alternatives.
Reference
+<boost/variant2/variant.hpp>
+Synopsis
+namespace boost {
+namespace variant2 {
+
+// in_place_type
+
+template<class T> struct in_place_type_t {};
+template<class T> constexpr in_place_type_t<T> in_place_type{};
+
+// in_place_index
+
+template<std::size_t I> struct in_place_index_t {};
+template<std::size_t I> constexpr in_place_index_t<I> in_place_index{};
+
+// variant
+
+template<class... T> class variant;
+
+// variant_size
+
+template<class T> struct variant_size {};
+
+template<class T> struct variant_size<T const>: variant_size<T> {};
+template<class T> struct variant_size<T volatile>: variant_size<T> {};
+template<class T> struct variant_size<T const volatile>: variant_size<T> {};
+
+template<class T> struct variant_size<T&>: variant_size<T> {}; // extension
+template<class T> struct variant_size<T&&>: variant_size<T> {}; // extension
+
+template<class T>
+ inline constexpr size_t variant_size_v = variant_size<T>::value;
+
+template<class... T>
+ struct variant_size<variant<T...>>:
+ std::integral_constant<std::size_t, sizeof...(T)> {};
+
+// variant_alternative
+
+template<size_t I, class T> struct variant_alternative {};
+
+template<size_t I, class T> struct variant_alternative<I, T const>;
+template<size_t I, class T> struct variant_alternative<I, T volatile>;
+template<size_t I, class T> struct variant_alternative<I, T const volatile>;
+
+template<size_t I, class T> struct variant_alternative<I, T&>; // extension
+template<size_t I, class T> struct variant_alternative<I, T&&>; // extension
+
+template<size_t I, class T>
+ using variant_alternative_t = typename variant_alternative<I, T>::type;
+
+template<size_t I, class... T>
+ struct variant_alternative<I, variant<T...>>;
+
+// variant_npos
+
+constexpr std::size_t variant_npos = -1;
+
+// holds_alternative
+
+template<class U, class... T>
+ constexpr bool holds_alternative(const variant<T...>& v) noexcept;
+
+// get
+
+template<size_t I, class... T>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ get(variant<T...>& v);
+template<size_t I, class... T>
+ constexpr variant_alternative_t<I, variant<T...>>&&
+ get(variant<T...>&& v);
+template<size_t I, class... T>
+ constexpr const variant_alternative_t<I, variant<T...>>&
+ get(const variant<T...>& v);
+template<size_t I, class... T>
+ constexpr const variant_alternative_t<I, variant<T...>>&&
+ get(const variant<T...>&& v);
+
+template<class U, class... T>
+ constexpr U& get(variant<T...>& v);
+template<class U, class... T>
+ constexpr U&& get(variant<T...>&& v);
+template<class U, class... T>
+ constexpr const U& get(const variant<T...>& v);
+template<class U, class... T>
+ constexpr const U&& get(const variant<T...>&& v);
+
+// get_if
+
+template<size_t I, class... T>
+ constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
+ get_if(variant<T...>* v) noexcept;
+template<size_t I, class... T>
+ constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
+ get_if(const variant<T...>* v) noexcept;
+
+template<class U, class... T>
+ constexpr add_pointer_t<U>
+ get_if(variant<T...>* v) noexcept;
+template<class U, class... T>
+ constexpr add_pointer_t<const U>
+ get_if(const variant<T...>* v) noexcept;
+
+// relational operators
+
+template<class... T>
+ constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);
+template<class... T>
+ constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);
+template<class... T>
+ constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);
+template<class... T>
+ constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);
+template<class... T>
+ constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);
+template<class... T>
+ constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);
+
+// visit
+
+template<class F, class... V>
+ constexpr /*see below*/ visit(F&& f, V&&... v);
+
+// monostate
+
+struct monostate {};
+
+constexpr bool operator==(monostate, monostate) noexcept { return true; }
+constexpr bool operator!=(monostate, monostate) noexcept { return false; }
+constexpr bool operator<(monostate, monostate) noexcept { return false; }
+constexpr bool operator>(monostate, monostate) noexcept { return false; }
+constexpr bool operator<=(monostate, monostate) noexcept { return true; }
+constexpr bool operator>=(monostate, monostate) noexcept { return true; }
+
+// swap
+
+template<class... T>
+ void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );
+
+// bad_variant_access
+
+class bad_variant_access;
+
+} // namespace variant2
+} // namespace boost
+variant
+namespace boost {
+namespace variant2 {
+
+template<class... T> class variant
+{
+public:
+
+ // constructors
+
+ constexpr variant() noexcept( /*see below*/ );
+
+ constexpr variant( variant const & r ) noexcept( /*see below*/ );
+ constexpr variant( variant&& r ) noexcept( /*see below*/ );
+
+ template<class U>
+ constexpr variant( U&& u ) noexcept( /*see below*/ );
+
+ template<class U, class... A>
+ constexpr explicit variant( in_place_type_t<U>, A&&... a );
+ template<class U, class V, class... A>
+ constexpr explicit variant( in_place_type_t<U>,
+ std::initializer_list<V> il, A&&... a );
+
+ template<size_t I, class... A>
+ constexpr explicit variant( in_place_index_t<I>, A&&... a );
+ template<size_t I, class V, class... A>
+ constexpr explicit variant( in_place_index_t<I>,
+ std::initializer_list<V> il, A&&... a );
+
+ // destructor
+
+ ~variant();
+
+ // assignment
+
+ constexpr variant& operator=( variant const & r ) noexcept( /*see below*/ );
+ constexpr variant& operator=( variant&& r ) noexcept( /*see below*/ );
+
+ template<class U> constexpr variant& operator=( U&& u ) noexcept( /*see below*/ );
+
+ // modifiers
+
+ template<class U, class... A>
+ constexpr U& emplace( A&&... a );
+ template<class U, class V, class... A>
+ constexpr U& emplace( std::initializer_list<V> il, A&&... a );
+
+ template<size_t I, class... A>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ emplace( A&&... a );
+ template<size_t I, class V, class... A>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ emplace( std::initializer_list<V> il, A&&... a );
+
+ // value status
+
+ constexpr bool valueless_by_exception() const noexcept;
+ constexpr size_t index() const noexcept;
+
+ // swap
+
+ void swap( variant& r ) noexcept( /*see below*/ );
+
+ // converting constructors (extension)
+
+ template<class... U> variant( variant<U...> const& r )
+ noexcept( /*see below*/ );
+
+ template<class... U> variant( variant<U...>&& r )
+ noexcept( /*see below*/ );
+
+ // subset (extension)
+
+ template<class... U> constexpr variant<U...> subset() & ;
+ template<class... U> constexpr variant<U...> subset() && ;
+ template<class... U> constexpr variant<U...> subset() const& ;
+ template<class... U> constexpr variant<U...> subset() const&& ;
+};
+
+} // namespace variant2
+} // namespace boost
+Constructors
+constexpr variant() noexcept( std::is_nothrow_default_constructible_v<T0> );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Constructs a
+variant
holding a value-initialized value of +typeT0
.
+ - Ensures: +
-
+
+index() == 0
.
+ - Throws: +
-
+
Any exception thrown by the value-initialization of
+T0
.
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +
+std::is_default_constructible_v<T0>
istrue
.
+
+
constexpr variant( variant const & w )
+ noexcept( mp_all<std::is_nothrow_copy_constructible<T>...>::value );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the variant to hold the same alternative and value as +
+w
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +
+std::is_copy_constructible_v<Ti>
istrue
for alli
.
+
+
constexpr variant( variant&& w )
+ noexcept( mp_all<std::is_nothrow_move_constructible<T>...>::value );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the variant to hold the same alternative and value as +
+w
.
+ - Throws: +
-
+
Any exception thrown by the move-initialization of the contained +value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +
+std::is_move_constructible_v<Ti>
istrue
for alli
.
+
+
template<class U> constexpr variant( U&& u ) noexcept(/*see below*/);
+-
+
-
+
+++
Let
+Tj
be a type that is determined as follows: build an imaginary function +FUN(Ti)
for each alternative typeTi
. The overloadFUN(Tj)
selected by +overload resolution for the expressionFUN(std::forward<U>(u))
defines the +alternativeTj
which is the type of the contained value after construction.++-
+
- Effects: +
-
+
Initializes
+*this
to hold the alternative typeTj
and +initializes the contained value fromstd::forward<U>(u)
.
+ - Ensures: +
-
+
+holds_alternative<Tj>(*this)
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
The expression inside
+noexcept
is equivalent to +std::is_nothrow_constructible_v<Tj, U>
. This function does not participate in +overload resolution unless++-
+
-
+
+sizeof…(T)
is nonzero,
+ -
+
+std::is_same_v<std::remove_cvref_t<U>, variant>
isfalse
,
+ -
+
+std::remove_cvref_t<U>
is neither a specialization ofin_place_type_t
nor a +specialization ofin_place_index_t
,
+ -
+
+std::is_constructible_v<Tj, U>
istrue
, and
+ -
+
the expression
+FUN(std::forward<U>(u))
is well-formed.
+
+ -
+
+
template<class U, class... A>
+ constexpr explicit variant( in_place_type_t<U>, A&&... a );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value of type
+U
with the arguments +std::forward<A>(a)…
.
+ - Ensures: +
-
+
+holds_alternative<U>(*this)
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +there is exactly one occurrence of
+U
inT…
and +std::is_constructible_v<U, A…>
is true.
+
+
template<class U, class V, class... A>
+ constexpr explicit variant( in_place_type_t<U>, std::initializer_list<V> il,
+ A&&... a );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value of type
+U
with the argumentsil
, +std::forward<A>(a)…
.
+ - Ensures: +
-
+
+holds_alternative<U>(*this)
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +there is exactly one occurrence of
+U
inT…
and +std::is_constructible_v<U, initializer_list<V>&, A…>
istrue
.
+
+
template<size_t I, class... A>
+ constexpr explicit variant( in_place_index_t<I>, A&&... a );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value of type
+TI
with the arguments +std::forward<A>(a)…
.
+ - Ensures: +
-
+
+index() == I
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +
+I < sizeof…(T)
andstd::is_constructible_v<TI, A…>
istrue
.
+
+
template<size_t I, class V, class... A>
+ constexpr explicit variant( in_place_index_t<I>, std::initializer_list<V> il,
+ A&&... a );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value of type
+TI
with the arguments +il
,std::forward<A>(a)…
.
+ - Ensures: +
-
+
+index() == I
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +
+I < sizeof…(T)
and +std::is_constructible_v<TI, initializer_list<V>&, A…>
istrue
.
+
+
Destructor
+~variant();
+-
+
-
+
+++
-
+
- Effects: +
-
+
Destroys the currently contained value.
+
+
+
Assignment
+constexpr variant& operator=( const variant& r )
+ noexcept( mp_all<std::is_nothrow_copy_constructible<T>...,
+ std::is_nothrow_copy_assignable<T>...>::value );
+-
+
-
+
+++
Let
+j
ber.index()
.++-
+
- Effects: +
-
+++
-
+
-
+
If
+index() == j
, assigns the value contained inr
to the value +contained in*this
.
+ -
+
Otherwise, equivalent to
+emplace<j>(get<j>(r))
.
+
+ -
+
- Returns: +
-
+
+*this
.
+ - Ensures: +
-
+
+index() == r.index()
.
+ - Remarks: +
-
+
This operator does not participate in overload resolution unless +
+std::is_copy_constructible_v<Ti> && std::is_copy_assignable_v<Ti>
is +true
for alli
.
+
+
constexpr variant& operator=( variant&& r )
+ noexcept( mp_all<std::is_nothrow_move_constructible<T>...,
+ std::is_nothrow_move_assignable<T>...>::value );
+-
+
-
+
+++
Let
+j
ber.index()
.++-
+
- Effects: +
-
+++
-
+
-
+
If
+index() == j
, assigns the value contained instd::move(r)
to the +value contained in*this
.
+ -
+
Otherwise, equivalent to
+emplace<j>(get<j>(std::move(r)))
.
+
+ -
+
- Returns: +
-
+
+*this
.
+ - Ensures: +
-
+
+index() == r.index()
.
+ - Remarks: +
-
+
This operator does not participate in overload resolution unless +
+std::is_move_constructible_v<Ti> && std::is_move_assignable_v<Ti>
is +true
for alli
.
+
+
template<class U> constexpr variant& operator=( U&& u )
+ noexcept( /*see below*/ );
+-
+
-
+
+++
Let
+Tj
be a type that is determined as follows: build an imaginary function +FUN(Ti)
for each alternative typeTi
. The overloadFUN(Tj)
selected by +overload resolution for the expressionFUN(std::forward<U>(u))
defines the +alternativeTj
which is the type of the contained value after construction.++-
+
- Effects: +
-
+++
-
+
-
+
If
+index() == j
, assignsstd::forward<U>(u)
to the value contained in +*this
.
+ -
+
Otherwise, equivalent to
+emplace<j>(std::forward<U>(u))
.
+
+ -
+
- Returns: +
-
+
+*this
.
+ - Ensures: +
-
+
+index() == j
.
+ - Remarks: +
-
+
The expression inside
+noexcept
isstd::is_nothrow_constructible_v<Tj, U> + && std::is_nothrow_assignable_v<Tj&, U>
. +This operator does not participate in overload resolution unless++-
+
-
+
+std::is_same_v<std::remove_cvref_t<T>, variant>
isfalse
,
+ -
+
+std::is_constructible_v<Tj, U> && std::is_assignable_v<Tj&, U>
is +true
, and
+ -
+
the expression
+FUN(std::forward<U>(u))
(withFUN
being the +above-mentioned set of imaginary functions) is well-formed.
+
+ -
+
+
Modifiers
+template<class U, class... A>
+ constexpr U& emplace( A&&... a );
+-
+
-
+
+++
Let
+I
be the zero-based index ofU
inT…
.++-
+
- Effects: +
-
+
Equivalent to:
+return emplace<I>(std::forward<A>(a)…);
+ - Remarks: +
-
+
This function shall not participate in overload resolution unless +
+std::is_constructible_v<U, A…>
istrue
andU
occurs exactly once +inT…
.
+
+
template<class U, class V, class... A>
+ constexpr U& emplace( std::initializer_list<V> il, A&&... a );
+-
+
-
+
+++
Let
+I
be the zero-based index ofU
inT…
.++-
+
- Effects: +
-
+
Equivalent to:
+return emplace<I>(il, std::forward<A>(a)…);
+ - Remarks: +
-
+
This function shall not participate in overload resolution unless +
+std::is_constructible_v<U, std::initializer_list<V>&, A…>
istrue
+andU
occurs exactly once inT…
.
+
+
template<size_t I, class... A>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ emplace( A&&... a );
+-
+
-
+
+++
-
+
- Requires: +
-
+
+I < sizeof(T…)
.
+ - Effects: +
-
+
Destroys the currently contained value, then initializes a new contained +value as if using the expression
+Ti(std::forward<A>(a)…)
.
+ - Ensures: +
-
+
+index() == I
.
+ - Returns: +
-
+
A reference to the new contained value.
+
+ - Remarks: +
-
+
This function shall not participate in overload resolution unless +
+std::is_constructible_v<Ti, A…>
istrue
.
+
+
template<size_t I, class V, class... A>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ emplace( std::initializer_list<V> il, A&&... a );
+-
+
-
+
+++
-
+
- Requires: +
-
+
+I < sizeof(T…)
.
+ - Effects: +
-
+
Destroys the currently contained value, then initializes a new contained +value as if using the expression
+Ti(il, std::forward<A>(a)…)
.
+ - Ensures: +
-
+
+index() == I
.
+ - Returns: +
-
+
A reference to the new contained value.
+
+ - Remarks: +
-
+
This function shall not participate in overload resolution unless +
+std::is_constructible_v<Ti, std::initializer_list<V>&, A…>
istrue
.
+
+
Value Status
+constexpr bool valueless_by_exception() const noexcept;
+-
+
-
+
+++
-
+
- Returns: +
-
+
+false
.
+
+
constexpr size_t index() const noexcept;
+-
+
-
+
+++
-
+
- Returns: +
-
+
The zero-based index of the active alternative.
+
+
+
Swap
+void swap( variant& r ) noexcept( mp_all<std::is_nothrow_move_constructible<T>...,
+ is_nothrow_swappable<T>...>::value );
+-
+
-
+
+++
-
+
- Effects: +
-
+++
-
+
-
+
If
+index() == r.index()
, callsswap(get<I>(*this), get<I>(r))
, +whereI
isindex()
.
+ -
+
Otherwise, as if +
+variant tmp(std::move(*this)); *this = std::move(r); r = std::move(tmp);
+
+ -
+
+
Converting Constructors (extension)
+template<class... U> variant( variant<U...> const& r )
+ noexcept( mp_all<std::is_nothrow_copy_constructible<U>...>::value );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value from the contained value of
+r
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +all types in
+U…
are inT…
and +std::is_copy_constructible_v<Ui>::value
istrue
for allUi
.
+
+
template<class... U> variant( variant<U...>&& r )
+ noexcept( mp_all<std::is_nothrow_move_constructible<U>...>::value );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Initializes the contained value from the contained value of +
+std::move(r)
.
+ - Throws: +
-
+
Any exception thrown by the initialization of the contained value.
+
+ - Remarks: +
-
+
This function does not participate in overload resolution unless +all types in
+U…
are inT…
and +std::is_move_constructible_v<Ui>::value
istrue
for allUi
.
+
+
Subset (extension)
+template<class... U> constexpr variant<U...> subset() & ;
+template<class... U> constexpr variant<U...> subset() const& ;
+-
+
-
+
+++
-
+
- Returns: +
-
+
A
+variant<U…>
whose contained value is copy-initialized from +the contained value of*this
and has the same type.
+ - Throws: +
-
+++
-
+
-
+
If the active alternative of
+*this
is not among the types inU…
, +bad_variant_access
.
+ -
+
Otherwise, any exception thrown by the initialization of the contained value.
+
+
+ -
+
- Remarks: +
-
+
This function does not participate in overload resolution unless +all types in
+U…
are inT…
and +std::is_copy_constructible_v<Ui>::value
istrue
for allUi
.
+
+
template<class... U> constexpr variant<U...> subset() && ;
+template<class... U> constexpr variant<U...> subset() const&& ;
+-
+
-
+
+++
-
+
- Returns: +
-
+
A
+variant<U…>
whose contained value is move-initialized from +the contained value of*this
and has the same type.
+ - Throws: +
-
+++
-
+
-
+
If the active alternative of
+*this
is not among the types inU…
, +bad_variant_access
.
+ -
+
Otherwise, any exception thrown by the initialization of the contained value.
+
+
+ -
+
- Remarks: +
-
+
This function does not participate in overload resolution unless +all types in
+U…
are inT…
and +std::is_move_constructible_v<Ui>::value
istrue
for allUi
.
+
+
variant_alternative
+template<size_t I, class T> struct variant_alternative<I, T const>;
+template<size_t I, class T> struct variant_alternative<I, T volatile>;
+template<size_t I, class T> struct variant_alternative<I, T const volatile>;
+template<size_t I, class T> struct variant_alternative<I, T&>; // extension
+template<size_t I, class T> struct variant_alternative<I, T&&>; // extension
+-
+
-
+
+++++++
If
+typename variant_alternative<I, T>::type
exists and isU
,++-
+
-
+
+variant_alternative<I, T const>::type
isU const
;
+ -
+
+variant_alternative<I, T volatile>::type
isU volatile
;
+ -
+
+variant_alternative<I, T const volatile>::type
isU const volatile
.
+ -
+
+variant_alternative<I, T&>::type
isU&
.
+ -
+
+variant_alternative<I, T&&>::type
isU&&
.
+
++Otherwise, these structs have no member
+type
.
+ -
+
template<size_t I, class... T>
+ struct variant_alternative<I, variant<T...>>;
+-
+
-
+
+++
When
+I < sizeof…(T)
, the nested typetype
is an alias for theI
-th +(zero-based) type inT…
. Otherwise, there is no membertype
.
+
holds_alternative
+template<class U, class... T>
+ constexpr bool holds_alternative(const variant<T...>& v) noexcept;
+-
+
-
+
+++
-
+
- Requires: +
-
+
The type
+U
occurs exactly once inT…
. Otherwise, the +program is ill-formed.
+ - Returns: +
-
+
+true
ifindex()
is equal to the zero-based index ofU
+inT…
.
+
+
get
+template<size_t I, class... T>
+ constexpr variant_alternative_t<I, variant<T...>>&
+ get(variant<T...>& v);
+template<size_t I, class... T>
+ constexpr variant_alternative_t<I, variant<T...>>&&
+ get(variant<T...>&& v);
+template<size_t I, class... T>
+ constexpr const variant_alternative_t<I, variant<T...>>&
+ get(const variant<T...>& v);
+template<size_t I, class... T>
+ constexpr const variant_alternative_t<I, variant<T...>>&&
+ get(const variant<T...>&& v);
+-
+
-
+
+++
-
+
- Effects: +
-
+
If
+v.index()
isI
, returns a reference to the object stored in +the variant. Otherwise, throwsbad_variant_access
.
+
+
template<class U, class... T>
+ constexpr U& get(variant<T...>& v);
+template<class U, class... T>
+ constexpr U&& get(variant<T...>&& v);
+template<class U, class... T>
+ constexpr const U& get(const variant<T...>& v);
+template<class U, class... T>
+ constexpr const U&& get(const variant<T...>&& v);
+-
+
-
+
+++
-
+
- Requires: +
-
+
The type
+U
occurs exactly once inT…
. Otherwise, the +program is ill-formed.
+ - Effects: +
-
+
If
+v
holds a value of typeU
, returns a reference to that value. +Otherwise, throwsbad_variant_access
.
+
+
get_if
+template<size_t I, class... T>
+ constexpr add_pointer_t<variant_alternative_t<I, variant<T...>>>
+ get_if(variant<T...>* v) noexcept;
+template<size_t I, class... T>
+ constexpr add_pointer_t<const variant_alternative_t<I, variant<T...>>>
+ get_if(const variant<T...>* v) noexcept;
+-
+
-
+
+++
-
+
- Requires: +
-
+
+I < sizeof…(U)
. Otherwise, the program is ill-formed.
+ - Effects: +
-
+
A pointer to the value stored in the variant, if +
+v != nullptr && v->index() == I
. Otherwise,nullptr
.
+
+
template<class U, class... T>
+ constexpr add_pointer_t<U>
+ get_if(variant<T...>* v) noexcept;
+template<class U, class... T>
+ constexpr add_pointer_t<const U>
+ get_if(const variant<T...>* v) noexcept;
+-
+
-
+
+++
-
+
- Requires: +
-
+
The type
+U
occurs exactly once inT…
. Otherwise, the +program is ill-formed.
+ - Effects: +
-
+
Equivalent to:
+return get_if<I>(v);
withI
being +the zero-based index ofU
inT…
.
+
+
Relational Operators
+template<class... T>
+ constexpr bool operator==(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+v.index() == w.index && get<I>(v) == get<I>(w)
, whereI
+isv.index()
.
+
+
template<class... T>
+ constexpr bool operator!=(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+!(v == w)
.
+
+
template<class... T>
+ constexpr bool operator<(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+v.index() < w.index || (v.index() == w.index && get<I>(v) < get<I>(w))
, +whereI
isv.index()
.
+
+
template<class... T>
+ constexpr bool operator>(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+w < v
.
+
+
template<class... T>
+ constexpr bool operator<=(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+v.index() < w.index || (v.index() == w.index && get<I>(v) <= get<I>(w))
, +whereI
isv.index()
.
+
+
template<class... T>
+ constexpr bool operator>=(const variant<T...>& v, const variant<T...>& w);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+w <= v
.
+
+
visit
+template<class F, class... V>
+ constexpr /*see below*/ visit(F&& f, V&&... v);
+-
+
-
+
+++
-
+
- Returns: +
-
+
+std::forward<F>(f)(get<I>(std::forward<V>(v))…)
, where +I…
isv.index()…
.
+
+
swap
+template<class... T>
+ void swap(variant<T...>& v, variant<T...>& w) noexcept( /*see below*/ );
+-
+
-
+
+++
-
+
- Effects: +
-
+
Equivalent to
+v.swap(w)
.
+
+
bad_variant_access
+class bad_variant_access: public std::exception
+{
+public:
+
+ bad_variant_access() noexcept = default;
+
+ char const * what() const noexcept
+ {
+ return "bad_variant_access";
+ }
+};
+Copyright and License
+This documentation is copyright 2018, 2019 Peter Dimov and is distributed under +the Boost Software License, Version 1.0.
+