Spec-Zone.ru › C++

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

Определён в заголовочном файле <variant>
template< class... Types >
constexpr bool operator==( const std::variant<Types...>& lhs,
                           const std::variant<Types...>& rhs );
(1) (начиная с C++17)
template< class... Types >
constexpr bool operator!=( const std::variant<Types...>& lhs,
                           const std::variant<Types...>& rhs );
(2) (начиная с C++17)
template< class... Types >
constexpr bool operator<( const std::variant<Types...>& lhs,
                          const std::variant<Types...>& rhs );
(3) (начиная с C++17)
template< class... Types >
constexpr bool operator>( const std::variant<Types...>& lhs,
                          const std::variant<Types...>& rhs );
(4) (начиная с C++17)
template< class... Types >
constexpr bool operator<=( const std::variant<Types...>& lhs,
                           const std::variant<Types...>& rhs );
(5) (начиная с C++17)
template< class... Types >
constexpr bool operator>=( const std::variant<Types...>& lhs,
                           const std::variant<Types...>& rhs );
(6) (начиная с 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) (начиная с C++20)
Вспомогательный шаблон функции
template< std::size_t I, class... Types >
constexpr const std::variant_alternative_t<I, std::variant<Types...>>&
    GET( const variant<Types...>& v );
(8) (только для иллюстрации*)

Выполняет операции сравнения объектов std::variant.

1-7) Сравнивает два объекта std::variant lhs и rhs. Содержащиеся значения сравниваются (с помощью соответствующего оператора для T) только в том случае, если оба lhs и rhs содержат значения, соответствующие одному и тому же индексу. В противном случае
  • lhs считается равным rhs тогда и только тогда, когда оба lhs и rhs не содержат значения.
  • lhs считается меньше rhs тогда и только тогда, когда либо rhs содержит значение, а lhs — нет, либо lhs.index() меньше rhs.index().
1-6) Пусть @ обозначает соответствующий оператор сравнения для каждой из этих функций:

Если для некоторых значений I соответствующее выражение GET <I>(lhs) @ GET <I>(rhs) некорректно или его результат нельзя преобразовать в bool, программа некорректна.

(до C++26)

Эта перегрузка участвует в разрешении перегрузки только в том случае, если для всех значений I соответствующее выражение GET <I>(lhs) @ GET <I>(rhs) корректно и его результат можно преобразовать в bool.

(начиная с C++26)
8) Шаблон функции GET, приведённый только для иллюстрации, работает как std::get(std::variant), за исключением того, что std::bad_variant_access никогда не выбрасывается.
Если I < sizeof...(Types) является false, программа некорректна.
Если I == v.index() является false, поведение не определено.

Параметры

lhs,rhs - варианты для сравнения

Возвращаемое значение

Оператор Оба операнда содержат значение
(пусть I будет lhs.index(), а J будет rhs.index())
lhs или rhs не содержит значения
(пусть lhs_empty будет lhs.valueless_by_exception(), а rhs_empty будет rhs.valueless_by_exception())
I и J равны I и J не равны
== 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() см. ниже

Для operator<=>:

  • Если только lhs не содержит значения, возвращает std::strong_ordering::less.
  • Если только rhs не содержит значения, возвращает std::strong_ordering::greater.
  • Если ни lhs, ни rhs не содержат значения, возвращает std::strong_ordering::equal.

Примечания

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__cpp_lib_constrained_equality 202403L (C++26) операторы сравнения с ограничениями для std::variant

Пример

#include <iostream>
#include <string>
#include <variant>

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
}

Вывод:

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

См. также

operator==operator!=operator<operator<=operator>operator>=operator<=>
(C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20)
сравнивает объекты optional
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/variant/operator_cmp

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API