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

来自cppreference.com
< cpp‎ | utility‎ | tuple


 
 
工具库
语言支持
类型支持(基本类型、RTTI)
库功能特性测试宏 (C++20)
动态内存管理
程序工具
协程支持 (C++20)
变参数函数
调试支持
(C++26)
三路比较
(C++20)
(C++20)(C++20)(C++20)
(C++20)(C++20)(C++20)
通用工具
日期和时间
函数对象
格式化库 (C++20)
(C++11)
关系运算符 (C++20 中弃用)
整数比较函数
(C++20)(C++20)(C++20)   
(C++20)
交换类型运算
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
常用词汇类型
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
初等字符串转换
(C++17)
(C++17)

 
 
在标头 <tuple> 定义
template< class... TTypes, class... UTypes >

bool operator==( const std::tuple<TTypes...>& lhs,

                 const std::tuple<UTypes...>& rhs );
(1) (C++11 起)
(C++14 起为 constexpr)
template< class... TTypes, class... UTypes >

bool operator!=( const std::tuple<TTypes...>& lhs,

                 const std::tuple<UTypes...>& rhs );
(2) (C++11 起)
(C++14 起为 constexpr)
(C++20 前)
template< class... TTypes, class... UTypes >

bool operator<( const std::tuple<TTypes...>& lhs,

                const std::tuple<UTypes...>& rhs );
(3) (C++11 起)
(C++14 起为 constexpr)
(C++20 前)
template< class... TTypes, class... UTypes >

bool operator<=( const std::tuple<TTypes...>& lhs,

                 const std::tuple<UTypes...>& rhs );
(4) (C++11 起)
(C++14 起为 constexpr)
(C++20 前)
template< class... TTypes, class... UTypes >

bool operator>( const std::tuple<TTypes...>& lhs,

                const std::tuple<UTypes...>& rhs );
(5) (C++11 起)
(C++14 起为 constexpr)
(C++20 前)
template< class... TTypes, class... UTypes >

bool operator>=( const std::tuple<TTypes...>& lhs,

                 const std::tuple<UTypes...>& rhs );
(6) (C++11 起)
(C++14 起为 constexpr)
(C++20 前)
template< class... TTypes, class... UTypes >

constexpr std::common_comparison_category_t<
    synth-three-way-result<TTypes, Elems>...>
    operator<=>( const std::tuple<TTypes...>& lhs,

                 const std::tuple<UTypes...>& rhs );
(7) (C++20 起)
template< class... TTypes, tuple-like UTuple >
constexpr bool operator==( const tuple<TTypes...>& lhs, const UTuple& rhs );
(8) (C++23 起)
template< class... TTypes, tuple-like UTuple >

constexpr std::common_comparison_category_t<
    synth-three-way-result<TTypes, /* Elems */>...>

    operator<=>( const tuple<TTypes...>& lhs, const UTuple& rhs );
(9) (C++23 起)
1,2)operator== 比较元组 lhs 的每个元素和元组 rhs 的对应元素。
1) 在每对对应元素都相等时返回 true
2) 返回 !(lhs == rhs)
如果 sizeof...(TTypes) 不等于 sizeof...(UTypes),或者 [0sizeof...(Types)) 中存在 i 使得 std::get<i>(lhs) == std::get<i>(rhs) 不是合法的表达式,那么程序非良构。
如果 [0sizeof...(Types)) 中存在 i 使得 std::get<i>(lhs) == std::get<i>(rhs) 不符合可布尔测试 (BooleanTestable) 要求,则行为未定义。
(C++26 前)
此重载只有在 sizeof...(TTypes) 等于 sizeof...(UTypes),而且对于 [0sizeof...(Types)) 中的每个 istd::get<i>(lhs) == std::get<i>(rhs) 为合法的表达式且 decltype(std::get<i>(lhs) == std::get<i>(rhs)) 实现 boolean-testable 时才会参与重载决议。
(C++26 起)
3-6)operator< 以字典序比较 lhsrhs,即首先比较首元素,在等价时比较第二元素,还等价时再比较第三元素,以此类推。
3) 对于空元组,返回 false。对于非空元组,其效果等价于
if (std::get<0>(lhs) < std::get<0>(rhs)) return true;

if (std::get<0>(rhs) < std::get<0>(lhs)) return false;
if (std::get<1>(lhs) < std::get<1>(rhs)) return true;
if (std::get<1>(rhs) < std::get<1>(lhs)) return false;
...

return std::get<N - 1>(lhs) < std::get<N - 1>(rhs);
4) 返回 !(rhs < lhs)
5) 返回 rhs < lhs
6) 返回 !(lhs < rhs)
如果 sizeof...(TTypes) 不等于 sizeof...(UTypes),或者等价的语句中展示的任何一个比较表达式不是合法的表达式,那么程序非良构。
如果等价的语句中展示的任何一个比较表达式的类型与值类别不符合可布尔测试 (BooleanTestable) 要求,则行为未定义。
7)synth-three-way 以字典序比较 lhsrhs,即首先比较首元素,在等价时比较第二元素,还等价时再比较第三元素,以此类推。

if (auto c = synth-three-way(std::get<0>(lhs), std::get<0>(rhs)); c != 0) return c;
if (auto c = synth-three-way(std::get<1>(lhs), std::get<1>(rhs)); c != 0) return c;
...
return synth-three-way(std::get<N - 1>(lhs), std::get<N - 1>(rhs));

8)(1),但 rhstuple-like 对象,并且 rhs 的元素数量改由 std::tuple_size_v<UTuple> 确定。此重载只能通过实参依赖查找找到。
9)(7),但 rhstuple-like 对象。/* Elems */ 表示包含 [0std::tuple_size_v<UTuple>) 中按升序的每个 i 对应的类型 std::tuple_element_t<i, UTuple> 的类型包。此重载只能通过实参依赖查找找到。

所有比较运算符都是短路的;它们在确定结果所必须的比较之外不会访问其他的元组元素。

<<=>>=!= 运算符分别从 operator<=>operator== 合成

(C++20 起)

参数

lhs, rhs - 要比较的元组

返回值

1,8) 在对于所有 [0sizeof...(Types)) 中的 i 都满足 std::get<i>(lhs) == std::get<i>(rhs) 时返回 true,否则返回 false。对两个空元组返回 true
2) !(lhs == rhs)
3)lhs 中的首个不等价元素小于 rhs 中的时候是 true,如果 rhs 中的首个不等价元素小于 lhs 中的或无不等价元素时返回 false。对两个空元组返回 false
4) !(rhs < lhs)
5) rhs < lhs
6) !(lhs < rhs)
7,9) 首对不等价元素(若存在)间的关系,否则返回 std::strong_ordering::equal。对两个空元组返回 std::strong_ordering::equal

注解

各关系运算符是基于各个元素的 operator< 定义的。

(C++20 前)

各关系运算符是基于 synth-three-way 定义的,若有可能则它会使用 operator<=>,否则使用 operator<

要注意,如果元素类型自身并不提供 operator<=>,但可以隐式转换为可三路比较的类型,则就会用这项转换来替代 operator<

(C++20 起)
功能特性测试 标准 功能特性
__cpp_lib_constrained_equality 202403L (C++26) std::tuple 的受约束 operator==

示例

因为 operator< 对于元组有定义,所以可以对元组的容器排序。

#include <algorithm>
#include <iostream>
#include <tuple>
#include <vector>
 
int main()
{
    std::vector<std::tuple<int, std::string, float>> v
    {
        {2, "baz", -0.1},
        {2, "bar", 3.14},
        {1, "foo", 10.1},
        {2, "baz", -1.1},
    };
    std::sort(v.begin(), v.end());
 
    for (const auto& p: v)
        std::cout << "{ " << get<0>(p)
                  << ", " << get<1>(p)
                  << ", " << get<2>(p)
                  << " }\n";
}

输出:

{ 1, foo, 10.1 }
{ 2, bar, 3.14 }
{ 2, baz, -1.1 }
{ 2, baz, -0.1 }

缺陷报告

下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。

缺陷报告 应用于 出版时的行为 正确行为
LWG 2114
(P2167R3)
C++11 缺少布尔运算的类型前条件 已添加

参阅

(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20 中移除)(C++20)
按字典序比较 pair 中的值
(函数模板)