当我试图了解 C++运算符时,我偶然发现了 cppreference.com上的一个奇怪的比较运算符,*在一个看起来像这样的表中:
“好吧,如果这些是 C++ 中的常用运算符,我最好学习它们”,我想。但我所有试图解开这个谜团的尝试都没有成功。即使在这里,在 Stack Overflow 上我的搜索也没有运气。
如果有,这个操作员究竟做了什么?
<=>
2017 年 11 月11日,ISO C 委员会采纳了 Herb Sutter关于 < => “宇宙飞船” 三路比较运算符的提议,作为添加到 **C20** 的新特性之一。在题为一致比较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_ 。 *
表达式 a <=> b*返回一个对象,如果 a < b比较 < 0 ,如果a > b比较 > 0 ,如果 a 和 b 相等/等价,则比较 ==0 。 ***
常见情况:* 要使用类型 Y编写类型 X 的所有比较,使用成员语义,只需编写: *
auto X::operator<=>(const Y&) =default;
高级案例:* 要编写类型 X 与类型 Y 的所有比较,只需编写带有 Y的 operator <=>,如果需要,可以使用 =default 获取成员语义,并返回适当的类别类型: ***
五个比较类别被定义为std::类型,每个具有以下预定义值:
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
equivalent
partial_ordering
strong_equality
unequal
weak_equality
nonequivalent
unordered
引入了<=>令牌。字符序列<=>标记为<= >, 在旧源代码中。例如,X<&Y::operator<=>需要添加一个空格来保留其含义。
<= >
X<&Y::operator<=>
可重载运算符<=>是一个三路比较函数,具有高于<和低于的优先级<<。它返回一个可以与文字进行比较的类型,0但允许其他返回类型,例如支持表达式模板。语言和标准库中定义的所有<=>运算符都返回上述 5std::种比较类别类型之一。
<
<<
0
对于语言类型,提供了以下内置的<=>同类型比较。所有都是 constexpr ,除非另有说明。不能使用标量提升/转换异构调用这些比较。
bool
operator<=>(T*, nullptr_t)
nullptr_t
T[N] <=> T[N]
T``<=>``<=>
void
为了更好地理解该运算符的内部工作原理,请阅读原始论文。这正是我使用搜索引擎发现的。