Namespaces
Variants

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

来自 zh.cppreference.net
 
 
 
 
定义于头文件 <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 <=> :

注释

功能测试 宏 值 标准 功能
__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 = "==";
        // 默认情况下 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; // 编译错误:无已知转换
    }
    // TODO: C++20 三路比较运算符 <=> 用于 variant
}

输出:

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 对象
(函数模板)