namespace std {
template <class... Types>
class variant;
template <class T> struct variant_size; template <class T> struct variant_size<const T>;
template <class T> struct variant_size<volatile T>;
template <class T> struct variant_size<const volatile T>;
template <class T>
inline constexpr size_t variant_size_v = variant_size<T>::value;
template <class... Types>
struct variant_size<variant<Types...>>;
template <size_t I, class T> struct variant_alternative; template <size_t I, class T> struct variant_alternative<I, const T>;
template <size_t I, class T> struct variant_alternative<I, volatile T>;
template <size_t I, class T> struct variant_alternative<I, const volatile T>;
template <size_t I, class T>
using variant_alternative_t = typename variant_alternative<I, T>::type;
template <size_t I, class... Types>
struct variant_alternative<I, variant<Types...>>;
inline constexpr size_t variant_npos = -1;
template <class T, class... Types>
constexpr bool holds_alternative(const variant<Types...>&) noexcept;
template <size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>&);
template <size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&&);
template <size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>&);
template <size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&&);
template <class T, class... Types>
constexpr T& get(variant<Types...>&);
template <class T, class... Types>
constexpr T&& get(variant<Types...>&&);
template <class T, class... Types>
constexpr const T& get(const variant<Types...>&);
template <class T, class... Types>
constexpr const T&& get(const variant<Types...>&&);
template <size_t I, class... Types>
constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
get_if(variant<Types...>*) noexcept;
template <size_t I, class... Types>
constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
get_if(const variant<Types...>*) noexcept;
template <class T, class... Types>
constexpr add_pointer_t<T>
get_if(variant<Types...>*) noexcept;
template <class T, class... Types>
constexpr add_pointer_t<const T>
get_if(const variant<Types...>*) noexcept;
template <class... Types>
constexpr bool operator==(const variant<Types...>&, const variant<Types...>&);
template <class... Types>
constexpr bool operator!=(const variant<Types...>&, const variant<Types...>&);
template <class... Types>
constexpr bool operator<(const variant<Types...>&, const variant<Types...>&);
template <class... Types>
constexpr bool operator>(const variant<Types...>&, const variant<Types...>&);
template <class... Types>
constexpr bool operator<=(const variant<Types...>&, const variant<Types...>&);
template <class... Types>
constexpr bool operator>=(const variant<Types...>&, const variant<Types...>&);
template <class Visitor, class... Variants>
constexpr see below visit(Visitor&&, Variants&&...);
struct monostate;
constexpr bool operator<(monostate, monostate) noexcept;
constexpr bool operator>(monostate, monostate) noexcept;
constexpr bool operator<=(monostate, monostate) noexcept;
constexpr bool operator>=(monostate, monostate) noexcept;
constexpr bool operator==(monostate, monostate) noexcept;
constexpr bool operator!=(monostate, monostate) noexcept;
template <class... Types>
void swap(variant<Types...>&, variant<Types...>&) noexcept(see below);
class bad_variant_access;
template <class T> struct hash;
template <class... Types> struct hash<variant<Types...>>;
template <> struct hash<monostate>;
template <class T, class Alloc> struct uses_allocator;
template <class... Types, class Alloc> struct uses_allocator<variant<Types...>, Alloc>;
}
namespace std {
template <class... Types>
class variant {
public:
constexpr variant() noexcept(see below);
variant(const variant&);
variant(variant&&) noexcept(see below);
template <class T>
constexpr variant(T&&) noexcept(see below);
template <class T, class... Args>
constexpr explicit variant(in_place_type_t<T>, Args&&...);
template <class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U>, Args&&...);
template <size_t I, class... Args>
constexpr explicit variant(in_place_index_t<I>, Args&&...);
template <size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U>, Args&&...);
template <class Alloc>
variant(allocator_arg_t, const Alloc&);
template <class Alloc>
variant(allocator_arg_t, const Alloc&, const variant&);
template <class Alloc>
variant(allocator_arg_t, const Alloc&, variant&&);
template <class Alloc, class T>
variant(allocator_arg_t, const Alloc&, T&&);
template <class Alloc, class T, class... Args>
variant(allocator_arg_t, const Alloc&, in_place_type_t<T>, Args&&...);
template <class Alloc, class T, class U, class... Args>
variant(allocator_arg_t, const Alloc&, in_place_type_t<T>,
initializer_list<U>, Args&&...);
template <class Alloc, size_t I, class... Args>
variant(allocator_arg_t, const Alloc&, in_place_index_t<I>, Args&&...);
template <class Alloc, size_t I, class U, class... Args>
variant(allocator_arg_t, const Alloc&, in_place_index_t<I>,
initializer_list<U>, Args&&...);
~variant();
variant& operator=(const variant&);
variant& operator=(variant&&) noexcept(see below);
template <class T> variant& operator=(T&&) noexcept(see below);
template <class T, class... Args>
T& emplace(Args&&...);
template <class T, class U, class... Args>
T& emplace(initializer_list<U>, Args&&...);
template <size_t I, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(Args&&...);
template <size_t I, class U, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U>, Args&&...);
constexpr bool valueless_by_exception() const noexcept;
constexpr size_t index() const noexcept;
void swap(variant&) noexcept(see below);
};
}
Any instance of
variant at any given time either holds a value
of one of its alternative types, or it holds no value
. When an instance of
variant holds a value of alternative type
T,
it means that a value of type
T, referred to as the
variant
object's
contained value, is allocated within the storage of the
variant object
. Implementations are not permitted to use additional storage, such as dynamic
memory, to allocate the contained value
. The contained value shall be allocated in a region of the
variant
storage suitably aligned for all types in
Types.... It is
implementation-defined
whether over-aligned types are supported
.All types in
Types... shall be (possibly cv-qualified)
object types that are not arrays
.A program that instantiates the definition of
variant with
no template arguments is ill-formed
.In the descriptions that follow, let
i be in the range
[0, sizeof...(Types)),
and be the type in
Types.... constexpr variant() noexcept(see below);
Effects:
Constructs a
variant holding a value-initialized value of type
. Postconditions:
valueless_by_exception() is
false and
index() is
0. Throws:
Any exception thrown by the value-initialization of
. Remarks:
This function shall be
constexpr if and only if the
value-initialization of the alternative type would satisfy the
requirements for a constexpr function
. The expression inside
noexcept is equivalent to
is_nothrow_default_constructible_v<>. This function shall not participate in overload resolution unless
is_default_constructible_v<> is
true. [
Note: See also class
monostate. —
end note ]
variant(const variant& w);
Effects:
If
w holds a value, initializes the
variant to hold the same
alternative as
w and direct-initializes the contained value
with
get<j>(w), where
j is
w.index(). Otherwise, initializes the
variant to not hold a value
.Throws:
Any exception thrown by direct-initializing any for all
i. Remarks:
This function shall not participate in overload resolution unless
is_copy_constructible_v<> is
true for all
i. variant(variant&& w) noexcept(see below);
Effects:
If
w holds a value, initializes the
variant to hold the same
alternative as
w and direct-initializes the contained value with
get<j>(std::move(w)), where
j is
w.index(). Otherwise, initializes the
variant to not hold a value
.Throws:
Any exception thrown by move-constructing any for all
i. Remarks:
The expression inside
noexcept is equivalent to the logical AND of
is_nothrow_move_constructible_v<> for all
i. This function shall not participate in overload resolution unless
is_move_constructible_v<> is
true for all
i.template <class T> constexpr variant(T&& t) noexcept(see below);
Let be a type that is determined as follows:
build an imaginary function
FUN() for each alternative type
. The overload
FUN() selected by overload
resolution for the expression
FUN(std::forward<T>(t)) defines
the alternative which is the type of the contained value after
construction
.Effects:
Initializes
*this to hold the alternative type and
direct-initializes the contained value as if direct-non-list-initializing it
with
std::forward<T>(t). Postconditions:
holds_alternative<>(*this) is
true. Throws:
Any exception thrown by the initialization of the selected alternative
. Remarks:
This function shall not participate in overload resolution unless
is_same_v<decay_t<T>, variant> is
false,
unless
decay_t<T> is neither
a specialization of
in_place_type_t
nor a specialization of
in_place_index_t,
unless
is_constructible_v<, T> is
true,
and unless the expression
FUN(
std::forward<T>(t)) (with
FUN
being the above-mentioned set of imaginary functions) is well formed
. [
Note:
variant<string, string> v("abc");
is ill-formed, as both alternative types have an equally viable constructor
for the argument
. —
end note ]
The expression inside
noexcept is equivalent to
is_nothrow_constructible_v<, T>. If 's selected constructor is a constexpr constructor,
this constructor shall be a constexpr constructor
.template <class T, class... Args> constexpr explicit variant(in_place_type_t<T>, Args&&... args);
Effects:
Initializes the contained value as if direct-non-list-initializing
an object of type
T
with the arguments
std::forward<Args>(args).... Postconditions:
holds_alternative<T>(*this) is
true. Throws:
Any exception thrown by calling the selected constructor of
T. Remarks:
This function shall not participate in overload resolution unless there is
exactly one occurrence of
T in
Types... and
is_constructible_v<T, Args...> is
true. If
T's selected constructor is a constexpr constructor, this
constructor shall be a constexpr constructor
.template <class T, class U, class... Args>
constexpr explicit variant(in_place_type_t<T>, initializer_list<U> il, Args&&... args);
Effects:
Initializes the contained value as if direct-non-list-initializing
an object of type
T
with the arguments
il, std::forward<Args>(args).... Postconditions:
holds_alternative<T>(*this) is
true. Throws:
Any exception thrown by calling the selected constructor of
T. Remarks:
This function shall not participate in overload resolution unless there is
exactly one occurrence of
T in
Types... and
is_constructible_v<T, initializer_list<U>&, Args...> is
true. If
T's selected constructor is a constexpr constructor, this
constructor shall be a constexpr constructor
.template <size_t I, class... Args> constexpr explicit variant(in_place_index_t<I>, Args&&... args);
Effects:
Initializes the contained value as if direct-non-list-initializing
an object of type
with the arguments
std::forward<Args>(args).... Postconditions:
index() is
I. Throws:
Any exception thrown by calling the selected constructor of
. Remarks:
This function shall not participate in overload resolution unless
If 's selected constructor is a constexpr constructor, this
constructor shall be a constexpr constructor
.template <size_t I, class U, class... Args>
constexpr explicit variant(in_place_index_t<I>, initializer_list<U> il, Args&&... args);
Effects:
Initializes the contained value as if direct-non-list-initializing
an object of type
with the arguments
il, std::forward<Args>(args).... Postconditions:
index() is
I. Remarks:
This function shall not participate in overload resolution unless
If 's selected constructor is a constexpr constructor, this
constructor shall be a constexpr constructor
.template <class Alloc>
variant(allocator_arg_t, const Alloc& a);
template <class Alloc>
variant(allocator_arg_t, const Alloc& a, const variant& v);
template <class Alloc>
variant(allocator_arg_t, const Alloc& a, variant&& v);
template <class Alloc, class T>
variant(allocator_arg_t, const Alloc& a, T&& t);
template <class Alloc, class T, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>, Args&&... args);
template <class Alloc, class T, class U, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_type_t<T>,
initializer_list<U> il, Args&&... args);
template <class Alloc, size_t I, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>, Args&&... args);
template <class Alloc, size_t I, class U, class... Args>
variant(allocator_arg_t, const Alloc& a, in_place_index_t<I>,
initializer_list<U> il, Args&&... args);
Effects:
Equivalent to the preceding constructors except that the contained value is
constructed with uses-allocator construction (
[allocator.uses.construction])
. ~variant();
Effects:
If
valueless_by_exception() is
false,
destroys the currently contained value
. Remarks:
If
is_trivially_destructible_v<> == true for all
then this destructor shall be a trivial destructor
. variant& operator=(const variant& rhs);
Effects:
If neither
*this nor
rhs holds a value, there is no effect
. Otherwise,
if
*this holds a value but
rhs does not, destroys the value
contained in
*this and sets
*this to not hold a value
. Otherwise,
if
index() == j, assigns the value contained in
rhs
to the value contained in
*this. Otherwise,
if either
is_nothrow_copy_constructible_v<> or
!is_nothrow_move_constructible_v<> is
true,
equivalent to
emplace<j>(get<j>(rhs)). Otherwise,
equivalent to
operator=(variant(rhs)).
Postconditions: index() == rhs.index(). Remarks:
This function shall not participate in overload resolution unless
is_copy_constructible_v<> &&
is_copy_assignable_v<>
is
true for all
i. variant& operator=(variant&& rhs) noexcept(see below);
Effects:
If neither
*this nor
rhs holds a value, there is no effect
. Otherwise,
if
*this holds a value but
rhs does not, destroys the value
contained in
*this and sets
*this to not hold a value
. Otherwise,
if
index() == j, assigns
get<j>(std::move(rhs)) to
the value contained in
*this. Otherwise,
equivalent to
emplace<j>(get<j>(std::move(rhs))).
Remarks:
This function shall not participate in overload resolution unless
is_move_constructible_v<> && is_move_assignable_v<> is
true for all
i. The expression inside
noexcept is equivalent to:
is_nothrow_move_constructible_v<> && is_nothrow_move_assignable_v<> for all
i. If an exception is thrown during the call to 's move construction
(with
j being
rhs.index()), the
variant will hold no value
.If an exception is thrown during the call to 's move assignment,
the state of the contained value is as defined by the exception safety
guarantee of 's move assignment;
index() will be
j.
template <class T> variant& operator=(T&& t) noexcept(see below);
Let be a type that is determined as follows:
build an imaginary function
FUN() for each alternative type
. The overload
FUN() selected by overload
resolution for the expression
FUN(std::forward<T>(t)) defines
the alternative which is the type of the contained value after
assignment
.Effects:
If
*this holds a , assigns
std::forward<T>(t) to
the value contained in
*this. Otherwise,
if
is_nothrow_constructible_v<, T> ||
!is_nothrow_move_constructible_v<> is
true,
equivalent to
emplace<j>(std::forward<T>(t)). Otherwise,
equivalent to
operator=(variant(std::forward<T>(t))).
Postconditions:
holds_alternative<>(*this) is
true, with
selected by the imaginary function overload resolution described above
. Remarks:
This function shall not participate in overload resolution unless
is_same_v<decay_t<T>, variant> is
false, unless
is_assignable_v<&, T> && is_constructible_v<, T> is
true,
and unless the expression
FUN(std::forward<T>(t)) (with
FUN being the above-mentioned set of imaginary functions)
is well formed
. [
Note:
variant<string, string> v;
v = "abc";
is ill-formed, as both alternative types have an equally viable constructor
for the argument
. —
end note ]
The expression inside
noexcept is equivalent to:
is_nothrow_assignable_v<T&, T> && is_nothrow_constructible_v<T, T>
If an exception is thrown during the assignment of
std::forward<T>(t)
to the value contained in
*this, the state of the contained value and
t are as defined by the exception safety guarantee of the assignment
expression;
valueless_by_exception() will be
false.If an exception is thrown during the initialization of the contained value,
the
variant object might not hold a value
.
template <class T, class... Args> T& emplace(Args&&... args);
Let
I be the zero-based index of
T in
Types....Effects:
Equivalent to: return emplace<I>(std::forward<Args>(args)...);
Remarks:
This function shall not participate in overload resolution unless
is_constructible_v<T, Args...> is
true, and
T occurs
exactly once in
Types.... template <class T, class U, class... Args> T& emplace(initializer_list<U> il, Args&&... args);
Let
I be the zero-based index of
T in
Types....Effects:
Equivalent to: return emplace<I>(il, std::forward<Args>(args)...);
Remarks:
This function shall not participate in overload resolution unless
is_constructible_v<T, initializer_list<U>&, Args...> is
true,
and
T occurs exactly once in
Types.... template <size_t I, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(Args&&... args);
Requires:
I < sizeof...(Types). Effects:
Destroys the currently contained value if
valueless_by_exception()
is
false. Then initializes the contained value as if direct-non-list-initializing
a value of type
with the arguments
std::forward<Args>(args)....Postconditions:
index() is
I. Returns:
A reference to the new contained value
. Throws:
Any exception thrown during the initialization of the contained value
. Remarks:
This function shall not participate in overload resolution unless
is_constructible_v<, Args...> is
true. If an exception is thrown during the initialization of the contained value,
the
variant might not hold a value
.template <size_t I, class U, class... Args>
variant_alternative_t<I, variant<Types...>>& emplace(initializer_list<U> il, Args&&... args);
Requires:
I < sizeof...(Types). Effects:
Destroys the currently contained value if
valueless_by_exception()
is
false. Then initializes the contained value as if direct-non-list-initializing
a value of type
with the arguments
il, std::forward<Args>(args)....Postconditions:
index() is
I. Returns:
A reference to the new contained value
. Throws:
Any exception thrown during the initialization of the contained value
. Remarks:
This function shall not participate in overload resolution unless
is_constructible_v<, initializer_list<U>&, Args...> is
true. If an exception is thrown during the initialization of the contained value,
the
variant might not hold a value
.constexpr bool valueless_by_exception() const noexcept;
Effects:
Returns
false if and only if the
variant holds a value
. [
Note: A
variant might not hold a value if an exception is thrown during a
type-changing assignment or emplacement
. The latter means that even a
variant<float, int> can become
valueless_by_exception(), for
instance by
struct S { operator int() { throw 42; }};
variant<float, int> v{12.f};
v.emplace<1>(S());
—
end note ]
constexpr size_t index() const noexcept;
Effects:
If
valueless_by_exception() is
true, returns
variant_npos. Otherwise, returns the zero-based index of the alternative of the contained value
.void swap(variant& rhs) noexcept(see below);
Requires: Lvalues of type shall be swappable (
[swappable.requirements]) and
is_move_constructible_v<> shall be
true for all
i. Effects:
if
valueless_by_exception() && rhs.valueless_by_exception() no effect
. Otherwise,
if
index() == rhs.index(), calls
swap(get<i>(*this), get<i>(rhs)) where
i is
index(). Otherwise,
exchanges values of
rhs and
*this.
Throws:
If
index() == rhs.index(),
any exception thrown by
swap(get<i>(*this), get<i>(rhs))
with
i being
index(). Otherwise, any exception thrown by the move constructor
of or
with
i being
index() and
j being
rhs.index().Remarks:
If an exception is thrown during the call to function
swap(get<i>(*this), get<i>(rhs)),
the states of the contained values of
*this and of
rhs are
determined by the exception safety guarantee of
swap for lvalues of
with
i being
index(). If an exception is thrown during the exchange of the values of
*this
and
rhs, the states of the values of
*this and of
rhs
are determined by the exception safety guarantee of
variant's move constructor
. The expression inside
noexcept is equivalent to the logical AND of
is_nothrow_move_constructible_v<> && is_nothrow_swappable_v<> for all
i.template <class T> struct variant_size;
Remarks:
All specializations of
variant_size shall meet the
UnaryTypeTrait requirements (
[meta.rqmts])
with a base characteristic of
integral_constant<size_t, N> for some
N. template <class T> class variant_size<const T>;
template <class T> class variant_size<volatile T>;
template <class T> class variant_size<const volatile T>;
Let
VS denote
variant_size<T> of the cv-unqualified
type
T. Then each of the three templates shall meet the
UnaryTypeTrait requirements (
[meta.rqmts]) with a
base characteristic of
integral_constant<size_t, VS::value>.template <class... Types>
struct variant_size<variant<Types...>> : integral_constant<size_t, sizeof...(Types)> { };
template <size_t I, class T> class variant_alternative<I, const T>;
template <size_t I, class T> class variant_alternative<I, volatile T>;
template <size_t I, class T> class variant_alternative<I, const volatile T>;
Let
VA denote
variant_alternative<I, T> of the
cv-unqualified type
T. Then each of the three templates shall
meet the
TransformationTrait requirements (
[meta.rqmts]) with a
member typedef
type that names the following type:
for the first specialization, add_const_t<VA::type>,
for the second specialization, add_volatile_t<VA::type>, and
for the third specialization,
add_cv_t<VA::type>.
variant_alternative<I, variant<Types...>>::type
Requires: I < sizeof...(Types). template <class T, class... Types>
constexpr bool holds_alternative(const variant<Types...>& v) noexcept;
Requires:
The type
T occurs exactly once in
Types.... Otherwise, the program is ill-formed
.Returns:
true if
index() is equal to the zero-based index of
T in
Types.... template <size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>& get(variant<Types...>& v);
template <size_t I, class... Types>
constexpr variant_alternative_t<I, variant<Types...>>&& get(variant<Types...>&& v);
template <size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>& get(const variant<Types...>& v);
template <size_t I, class... Types>
constexpr const variant_alternative_t<I, variant<Types...>>&& get(const variant<Types...>&& v);
Requires:
I < sizeof...(Types). Otherwise the program is ill-formed
.Effects:
If
v.index() is
I, returns a reference to the object stored in
the
variant. Otherwise, throws an exception of type
bad_variant_access.template <class T, class... Types> constexpr T& get(variant<Types...>& v);
template <class T, class... Types> constexpr T&& get(variant<Types...>&& v);
template <class T, class... Types> constexpr const T& get(const variant<Types...>& v);
template <class T, class... Types> constexpr const T&& get(const variant<Types...>&& v);
Requires:
The type
T occurs exactly once in
Types.... Otherwise, the program is ill-formed
.Effects:
If
v holds a value of type
T, returns a reference to that value
. Otherwise, throws an exception of type
bad_variant_access.template <size_t I, class... Types>
constexpr add_pointer_t<variant_alternative_t<I, variant<Types...>>>
get_if(variant<Types...>* v) noexcept;
template <size_t I, class... Types>
constexpr add_pointer_t<const variant_alternative_t<I, variant<Types...>>>
get_if(const variant<Types...>* v) noexcept;
Requires:
I < sizeof...(Types). Otherwise the program is ill-formed
.Returns:
A pointer to the value stored in the
variant, if
v != nullptr
and
v->index() == I. Otherwise, returns
nullptr.template <class T, class... Types>
constexpr add_pointer_t<T>
get_if(variant<Types...>* v) noexcept;
template <class T, class... Types>
constexpr add_pointer_t<const T>
get_if(const variant<Types...>* v) noexcept;
Requires:
The type
T occurs exactly once in
Types.... Otherwise, the program is ill-formed
.Effects:
Equivalent to:
return get_if<i>(v); with
i being the zero-based
index of
T in
Types.... template <class... Types>
constexpr bool operator==(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) == get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
v.index() != w.index(),
false;
otherwise if
v.valueless_by_exception(),
true;
otherwise
get<i>(v) == get<i>(w) with
i being
v.index(). template <class... Types>
constexpr bool operator!=(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) != get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
v.index() != w.index(),
true;
otherwise if
v.valueless_by_exception(),
false;
otherwise
get<i>(v) != get<i>(w) with
i being
v.index(). template <class... Types>
constexpr bool operator<(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) < get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
w.valueless_by_exception(),
false;
otherwise if
v.valueless_by_exception(),
true;
otherwise, if
v.index() < w.index(),
true;
otherwise if
v.index() > w.index(),
false;
otherwise
get<i>(v) < get<i>(w) with
i being
v.index(). template <class... Types>
constexpr bool operator>(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) > get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
v.valueless_by_exception(),
false;
otherwise if
w.valueless_by_exception(),
true;
otherwise, if
v.index() > w.index(),
true;
otherwise if
v.index() < w.index(),
false;
otherwise
get<i>(v) > get<i>(w) with
i being
v.index(). template <class... Types>
constexpr bool operator<=(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) <= get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
v.valueless_by_exception(),
true;
otherwise if
w.valueless_by_exception(),
false;
otherwise, if
v.index() < w.index(),
true;
otherwise if
v.index() > w.index(),
false;
otherwise
get<i>(v) <= get<i>(w) with
i being
v.index(). template <class... Types>
constexpr bool operator>=(const variant<Types...>& v, const variant<Types...>& w);
Requires:
get<i>(v) >= get<i>(w) is a valid expression returning a type that is
convertible to
bool, for all
i. Returns:
If
w.valueless_by_exception(),
true;
otherwise if
v.valueless_by_exception(),
false;
otherwise, if
v.index() > w.index(),
true;
otherwise if
v.index() < w.index(),
false;
otherwise
get<i>(v) >= get<i>(w) with
i being
v.index().