operator==, !=, <, <=, >, >=, <=>(std::variant) (original) (raw)

Defined in header
template< class... Types > constexpr bool operator==( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (1) (since C++17)
template< class... Types > constexpr bool operator!=( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (2) (since C++17)
template< class... Types > constexpr bool operator<( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (3) (since C++17)
template< class... Types > constexpr bool operator>( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (4) (since C++17)
template< class... Types > constexpr bool operator<=( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (5) (since C++17)
template< class... Types > constexpr bool operator>=( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (6) (since C++17)
template< class... Types > constexpr std::common_comparison_category_t <std::compare_three_way_result_t<Types>...> operator<=>( const std::variant<Types...>& lhs, const std::variant<Types...>& rhs ); (7) (since C++20)
Helper function template
template< std::size_t I, class... Types > constexpr const std::variant_alternative_t<I, std::variant<Types...>>& GET( const variant<Types...>& v ); (8) (exposition only*)

Performs comparison operations on std::variant objects.

1-7) Compares two std::variant objects lhs and rhs. The contained values are compared (using the corresponding operator of T) only if both lhs and rhs contain values corresponding to the same index. Otherwise,

1-6) Let @ denote the corresponding comparison operator, for each of these functions:

If, for some values of I, the corresponding expression GET <I>(lhs) @ GET <I>(rhs) is ill-formed or its result is not convertible to bool, the program is ill-formed. (until C++26)
This overload participates in overload resolution only if for all values of I, the corresponding expression GET <I>(lhs) @ GET <I>(rhs) is well-formed and its result is convertible to bool. (since C++26)

If I < sizeof...(Types) is false, the program is ill-formed.

If I == v.index() is false, the behavior is undefined.

[edit] Parameters

lhs,rhs - variants to compare

[edit] Return value

Operator Both operands contains a value(let I be lhs.index() and J be rhs.index()) lhs or rhs is valueless(let lhs_empty be lhs.valueless_by_exception() and rhs_empty be rhs.valueless_by_exception())
I and J are equal I and J are unequal
== GET <I>(lhs) == GET <I>(rhs) false lhs_empty && rhs_empty
!= GET <I>(lhs) != GET <I>(rhs) true lhs_empty != rhs_empty
< GET <I>(lhs) < _GET_ <I>(rhs) lhs.index() < rhs.index() lhs_empty && !rhs_empty
> GET <I>(lhs) > GET <I>(rhs) lhs.index() > rhs.index() !lhs_empty && rhs_empty
<= GET <I>(lhs) <= _GET_ <I>(rhs) lhs.index() < rhs.index() lhs_empty
>= GET <I>(lhs) >= GET <I>(rhs) lhs.index() > rhs.index() rhs_empty
<=> GET <I>(lhs) <=> GET <I>(rhs) lhs.index() <=> rhs.index() see below

For operator<=>:

[edit] Notes

Feature-test macro Value Std Feature
__cpp_lib_constrained_equality 202403L (C++26) constrained comparison operators for std::variant

[edit] Example

#include #include #include   int main() { std::cout << std::boolalpha; std::string cmp; bool result;   auto print2 = [&cmp, &result](const auto& lhs, const auto& rhs) { std::cout << lhs << ' ' << cmp << ' ' << rhs << " : " << result << '\n'; };   std::variant<int, std::string> v1, v2;   std::cout << "operator==\n"; { cmp = "==";   // by default v1 = 0, v2 = 0; result = v1 == v2; // true std::visit(print2, v1, v2);   v1 = v2 = 1; result = v1 == v2; // true std::visit(print2, v1, v2);   v2 = 2; result = v1 == v2; // false std::visit(print2, v1, v2);   v1 = "A"; result = v1 == v2; // false: v1.index == 1, v2.index == 0 std::visit(print2, v1, v2);   v2 = "B"; result = v1 == v2; // false std::visit(print2, v1, v2);   v2 = "A"; result = v1 == v2; // true std::visit(print2, v1, v2); }   std::cout << "operator<\n"; { cmp = "<";   v1 = v2 = 1; result = v1 < v2; // false std::visit(print2, v1, v2);   v2 = 2; result = v1 < v2; // true std::visit(print2, v1, v2);   v1 = 3; result = v1 < v2; // false std::visit(print2, v1, v2);   v1 = "A"; v2 = 1; result = v1 < v2; // false: v1.index == 1, v2.index == 0 std::visit(print2, v1, v2);   v1 = 1; v2 = "A"; result = v1 < v2; // true: v1.index == 0, v2.index == 1 std::visit(print2, v1, v2);   v1 = v2 = "A"; result = v1 < v2; // false std::visit(print2, v1, v2);   v2 = "B"; result = v1 < v2; // true std::visit(print2, v1, v2);   v1 = "C"; result = v1 < v2; // false std::visit(print2, v1, v2); }   { std::variant<int, std::string> v1; std::variant<std::string, int> v2; // v1 == v2; // Compilation error: no known conversion }   // TODO: C++20 three-way comparison operator <=> for variants }

Output:

operator== 0 == 0 : true 1 == 1 : true 1 == 2 : false A == 2 : false A == B : false A == A : true operator< 1 < 1 : false 1 < 2 : true 3 < 2 : false A < 1 : false 1 < A : true A < A : false A < B : true C < B : false

[edit] See also