variant_operator_cmp

variant_operator_cmp (variant 비교 연산자)

std::variant 객체에 대한 비교 연산을 수행하는 연산자들을 설명하는 페이지예요. 이 연산자들은 variant가 현재 보관하고 있는 값의 타입과 인덱스를 기준으로 동등 비교, 크기 비교, 삼자 비교를 수행해요. C++17부터 사용할 수 있고, C++20에서 우주선 연산자(<=>)도 추가되었어요.

출처: cppreference

본문

연산자 선언

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* )

이 연산자들은 std::variant 객체에 대한 비교 연산을 수행해요.

  • lhs는 rhs와 같다고 간주해요. 단, lhs와 rhs 모두 값을 보관하지 않을 때만 그렇고요.
  • lhs는 rhs보다 작다고 간주해요. 단, rhs가 값을 보관하고 lhs가 보관하지 않거나, lhs.index()rhs.index()보다 작을 때만 그렇고요.

만약 어떤 I 값에 대해 GET < I > ( lhs ) @ GET < I > ( rhs ) 표현식이 ill-formed이거나 그 결과가 bool로 변환할 수 없으면, 프로그램은 ill-formed예요. (C++26까지)

C++26부터는 이 오버로드가 모든 I 값에 대해 GET < I > ( lhs ) @ GET < I > ( rhs ) 표현식이 well-formed이고 그 결과가 bool로 변환 가능할 때만 오버로드 해석에 참여해요.

매개변수

lhs, rhs - 비교할 variant

반환값

연산자 두 피연산자가 값을 가질 때 (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
!= GET < I > ( lhs ) != GET < I > ( rhs ) true
< GET < I > ( lhs ) < GET < I > ( rhs ) lhs . index () < rhs . index ()
> GET < I > ( lhs ) > GET < I > ( rhs ) lhs . index () > rhs . index ()
<= GET < I > ( lhs ) <= GET < I > ( rhs ) lhs . index () < rhs . index ()
>= GET < I > ( lhs ) >= GET < I > ( rhs ) lhs . index () > rhs . index ()
<=> 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을 반환해요.

Notes

Feature-test macro 표준 기능
__cpp_lib_constrained_equality 202403L (C++26) std::variant에 대한 제약된 비교 연산자

Example

#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

See also

operator== operator!= operator< operator<= operator> operator>= operator<=> (C++17) (C++17) (C++17) (C++17) (C++17) (C++17) (C++20) optional 객체를 비교해요 (함수 템플릿)

더 알아보기 (Learn more)

cppreference