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
。偏序关系允许类型中存在两个值之间没有比较关系,弱序关系则可以忽略传递性。
快速练习
下面的表达式的值是