小编典典

什么是 C++ 中的 <=>(“宇宙飞船”,三向比较)运算符?

all

当我试图了解 C++运算符时,我偶然发现了
cppreference.com上的一个奇怪的比较运算符,*在一个看起来像这样的表中:

在此处输入图像描述

“好吧,如果这些是 C++ 中的常用运算符,我最好学习它们”,我想。但我所有试图解开这个谜团的尝试都没有成功。即使在这里,在 Stack Overflow
上我的搜索也没有运气。

< =>C++ 之间有联系吗?

如果有,这个操作员究竟做了什么?


阅读 125

收藏
2022-05-18

共1个答案

小编典典

2017 年 11 月11日,ISO C 委员会采纳了 Herb
Sutter
关于 < => “宇宙飞船” 三路比较运算符的提议,作为添加到
**C
20** 的新特性之一。在题为一致比较Sutter、Maurer 和 Brown
的论文中,展示了新设计的概念。有关该提案的概述,这里是文章的摘录:

表达式 a <=> b*返回一个对象,如果 a < b比较 < 0 ,如果a > b比较 > 0 ,如果 a 和
b 相等/等价,则比较 ==0 。
***

常见情况:* 要使用类型 Y编写类型 X 的所有比较,使用成员语义,只需编写: *

auto X::operator<=>(const Y&) =default;

高级案例:* 要编写类型 X 与类型 Y 的所有比较,只需编写带有 Y的 operator
<=>
,如果需要,可以使用 =default 获取成员语义,并返回适当的类别类型:
***

  • 如果您的类型自然支持 <* ,则返回 _ordering ,并且我们将有效地生成对称 <><
    =
    > ===!= ;否则返回 _equality ,我们将有效地生成对称 ==
    !=
    ***
  • 如果您的类型 a == b* 意味着 f(a) == f(b) (可替代性,其中 f 仅读取可使用公共 const
    成员访问的比较显着状态),则返回 strong_ , 否则 返回 weak_
    *

比较类别

五个比较类别被定义为std::类型,每个具有以下预定义值:

+--------------------------------------------------------------------+
|                  |          Numeric  values          | Non-numeric |
|     Category     +-----------------------------------+             |
|                  | -1   | 0          | +1            |   values    |
+------------------+------+------------+---------------+-------------+
| strong_ordering  | less | equal      | greater       |             |
| weak_ordering    | less | equivalent | greater       |             |
| partial_ordering | less | equivalent | greater       | unordered   |
| strong_equality  |      | equal      | nonequal      |             |
| weak_equality    |      | equivalent | nonequivalent |             |
+------------------+------+------------+---------------+-------------+

这些类型之间的隐式转换定义如下:

  • strong_ordering使用值 { less, equal, greater} 隐式转换为:
    • weak_ordering具有值 { less, equivalent, greater}
    • partial_ordering具有值 { less, equivalent, greater}
    • strong_equality具有值 { unequal, equal, unequal}
    • weak_equality具有值 { nonequivalent, equivalent, nonequivalent}
  • weak_ordering使用值 { less, equivalent, greater} 隐式转换为:
    • partial_ordering具有值 { less, equivalent, greater}
    • weak_equality具有值 { nonequivalent, equivalent, nonequivalent}
  • partial_ordering使用值 { less, equivalent, greater, unordered} 隐式转换为:
    • weak_equality具有值 { nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equality使用值 { equal, unequal} 隐式转换为:
    • weak_equality有值 { equivalent, nonequivalent}

三路比较

引入了<=>令牌。字符序列<=>标记为<= >, 在旧源代码中。例如,X<&Y::operator<=>需要添加一个空格来保留其含义。

可重载运算符<=>是一个三路比较函数,具有高于<和低于的优先级<<。它返回一个可以与文字进行比较的类型,0但允许其他返回类型,例如支持表达式模板。语言和标准库中定义的所有<=>运算符都返回上述
5std::种比较类别类型之一。

对于语言类型,提供了以下内置的<=>同类型比较。所有都是 constexpr ,除非另有说明。不能使用标量提升/转换异构调用这些比较。

  • 对于bool、整数和指针类型,<=>返回strong_ordering
  • 对于指针类型,允许不同的 cv 限定和派生到基的转换调用同构的内置<=>,并且有内置的异类operator<=>(T*, nullptr_t)。只有指向相同对象/分配的指针的比较才是常量表达式。
  • 对于基本浮点类型,可以通过<=>partial_ordering参数扩展为更大的浮点类型来异构调用。
  • 对于枚举,<=>返回与枚举的基础类型相同的<=>.
  • 对于nullptr_t,<=>返回strong_ordering并且总是产生equal
  • 对于可复制数组,返回与’sT[N] <=> T[N]相同的类型并执行字典元素比较。其他数组没有。T``<=>``<=>
  • 因为void没有<=>

为了更好地理解该运算符的内部工作原理,请阅读原始论文。这正是我使用搜索引擎发现的。

2022-05-18