命名空间
联合体变体 (Variants)
视图 (Views)
操作 (Actions)

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

来自 cppreference.cn
< cpp‎ | utility‎ | 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 对象 lhsrhs。仅当 lhsrhs 都包含与同一索引对应的值时,才比较包含的值(使用 T 的相应运算符)。否则,
  • 当且仅当 lhsrhs 都不包含值时,lhs 才被认为等于 rhs
  • 当且仅当 rhs 包含值且 lhs 不包含值,或者 lhs.index() 小于 rhs.index() 时,lhs 才被认为小于 rhs
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 - 要比较的变体

[编辑] 返回值

 运算符  两个操作数都包含值
(令 Ilhs.index()Jrhs.index()
lhsrhs 无值
(令 lhs_emptylhs.valueless_by_exception()rhs_emptyrhs.valueless_by_exception()
IJ 相等 IJ 不相等
== 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<=>

[编辑] 注解

特性测试 Std 特性
__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

[编辑] 参见

(C++17)(C++17)(C++17)(C++17)(C++17)(C++17)(C++20)
比较 optional 对象
(函数模板) [编辑]