2.2.7 关系表达式
比较表达式、关系表达式、相等表达式三者组成了 C++ 中的比较关系,它们的形式如下:
比较表达式
- 比较表达式 <=> 移位表达式
- 移位表达式
关系表达式
- 关系表达式 < 比较表达式
- 关系表达式 > 比较表达式
- 关系表达式 <= 比较表达式
- 关系表达式 >= 比较表达式
- 比较表达式
其中,< 表示小于,> 表示大于,<= 表示小于等于,>= 表示大于等于。
相等表达式
- 相等表达式 == 关系表达式
- 相等表达式 != 关系表达式
- 关系表达式
其中,== 表示等于,!= 表示不等于。注意,表示等于时,中间的运算符是两个等号 ==,而不是一个等号 =。
关系表达式与相等表达式的计算
比较表达式和关系表达式的结果都是 bool 类型。例如:
42 < 24 // 值为 false
42 > 24 // 值为 true
42 <= 42 // 值为 true
24 >= 42 // 值为 false
42 == 42 // 值为 true
42 != 42 // 值为 false如果两边的表达式的类型不同,C++ 会尝试将两边转换为类型大小较大的那个类型。例如:
'a' < 42 // 值为 false这里,'a' 被转换为 int 类型,然后再进行比较。'a'的ASCII码是65,所以这个比较的结果是 65 < 42,得到 false。
注意,不要连用两个比较运算符,例如24 < a < 42。这样的表达式会导致计算 24 < a 的结果,得到一个 bool 值,然后这个值(假定为x)再计算 x < 42。这样的计算中,bool 被转换为 int 类型(因为比较的右边是 int 类型),结果x要么是0 要么是 1,然后和 42 比较,这显然不会得到我们想要的结果。
比较表达式的计算
<=> 表示三路比较,<=> 的结果是一个整数,如果左边的值小于右边的值,结果是负数;如果左边的值等于右边的值,结果是0;如果左边的值大于右边的值,结果是正数。例如:
(42 <=> 24) > 0 // 值为 true
(42 <=> 42) == 0 // 值为 true
(24 <=> 42) < 0 // 值为 true三路比较是什么?
技术性地说,int 类型的三路比较的结果是一个 std::strong_ordering 类型的值,包括 less、equal、greater 三个值,这三个值可以与0做比较。这里为了方便理解,简化了三路比较的结果。
std::strong_ordering 表达的是全序关系。对于某个具有全序关系的类型的值 a 、 b 和 c,有:
- 反对称性:如果 a <= b且b <= a成立,那么a == b。
- 传递性:如果 a <= b且b <= c,那么a <= c。
- 反自反性:a <= a总是成立。
这时候,两个数据的比较常常能够用差值的符号性来表示,这样能最大程度利用一次比较的信息量。
除了全序关系,还有偏序关系 std::partial_ordering 和弱序关系 std::weak_ordering。偏序关系允许类型中存在两个值之间没有比较关系,弱序关系则可以忽略传递性。
快速练习
下面的表达式的值是