C++ 中的 <=> 运算符是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47466358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:42:32  来源:igfitidea点击:

What is the <=> operator in C++?

c++operatorsc++-faqc++20spaceship-operator

提问by q-l-p

While I was trying to learn about C++operators, I stumbled upon a strange comparison operator on cppreference.com,*in a table that looked like this:

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

enter image description here

在此处输入图片说明

"Well, if these are common operators in C++, I better learn them", I thought. But all my attempts to elucidate this mystery were unsuccessful. Even here, on Stack Overflow I had no luck in my search.

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

Is there a connection between <=>and C++?

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

And if there is, what does this operator do exactly?

如果有,这个操作符究竟是做什么的?

* In the meantime cppreference.com updated that page and now contains information about the<=>operator.

* 与此同时,cppreference.com 更新了该页面,现在包含有关<=>运营商的信息。

采纳答案by q-l-p

On 2017-11-11, the ISO C++ committee adopted Herb Sutter's proposal for the <=> "spaceship" three-way comparison operatoras one of the new features that were added to C++20. In the paper titled Consistent comparisonSutter, Maurer and Brown demonstrate the concepts of the new design. For an overview of the proposal, here's an excerpt from the article:

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

The expression a <=> breturns an object that compares <0if a < b, compares >0if a > b, and compares ==0if a and b are equal/equivalent.

Common case:To write all comparisons for your type Xwith type Y, with memberwise semantics, just write:

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

Advanced cases:To write all comparisons for your type Xwith type Y, just write operator<=>that takes a Y, can use =defaultto get memberwise semantics if desired, and returns the appropriate category type:

  • Return an _orderingif your type naturally supports <, and we'll efficiently generate symmetric <, >, <=, >=, ==, and !=; otherwise return an _equality, and we'll efficiently generate symmetric ==and !=.
  • Return strong_if for your type a == bimplies f(a) == f(b)(substitutability, where freads only comparison-salient state that is accessible using the public constmembers), otherwise return weak_.

表达一个<=> b返回,其比较的对象<0如果A <B ,比较> 0如果A> B,并且比较== 0如果a和b相等/当量。

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

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

晚期病例:要写出你的类型所有比较XŸ,只写操作<=>,需要一个Ÿ,可以使用 =默认获得按成员语义如果需要的话,并返回相应的类别类型:

  • 如果您的类型自然支持<,则返回_ordering,我们将有效地生成对称<><=>===!=;否则返回_equality,我们将有效地生成对称==!=
  • 返回strong_如果你的类型一个== b意味着F(一)== F(B) (可替代性,其中˚F只读取比较隐状态是访问使用公共常量成员),否则返回 weak_

Comparison Categories

比较类别

Five comparison categories are defined as std::types, each having the following predefined values:

五个比较类别被定义为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 |             |
+------------------+------+------------+---------------+-------------+

Implicit conversions between these types are defined as follows:

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

  • strong_orderingwith values {less, equal, greater} implicitly converts to:
    • weak_orderingwith values {less, equivalent, greater}
    • partial_orderingwith values {less, equivalent, greater}
    • strong_equalitywith values {unequal, equal, unequal}
    • weak_equalitywith values {nonequivalent, equivalent, nonequivalent}
  • weak_orderingwith values {less, equivalent, greater} implicitly converts to:
    • partial_orderingwith values {less, equivalent, greater}
    • weak_equalitywith values {nonequivalent, equivalent, nonequivalent}
  • partial_orderingwith values {less, equivalent, greater, unordered} implicitly converts to:
    • weak_equalitywith values {nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equalitywith values {equal, unequal} implicitly converts to:
    • weak_equalitywith values {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}

Three-way comparison

三路比较

The<=>token is introduced. The character sequence<=>tokenizes to<= >, in old source code. For example,X<&Y::operator<=>needs to add a space to retain its meaning.

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

The overloadable operator<=>is a three-way comparison function and has precedence higher than<and lower than<<. It returns a type that can be compared against literal0but other return types are allowed such as to support expression templates. All<=>operators defined in the language and in the standard library return one of the 5 aforementionedstd::comparison category types.

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

For language types, the following built-in<=>same-type comparisons are provided. All are constexpr, except where noted otherwise. These comparisons cannot be invoked heterogeneously using scalar promotions/conversions.

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

  • Forbool, integral, and pointer types,<=>returnsstrong_ordering.
  • For pointer types, the different cv-qualifications and derived-to-base conversions are allowed to invoke a homogeneous built-in<=>, and there are built-in heterogeneousoperator<=>(T*, nullptr_t). Only comparisons of pointers to the same object/allocation are constant expressions.
  • For fundamental floating point types,<=>returnspartial_ordering, and can be invoked heterogeneously by widening arguments to a larger floating point type.
  • For enumerations,<=>returns the same as the enumeration's underlying type's<=>.
  • Fornullptr_t,<=>returnsstrong_orderingand always yieldsequal.
  • For copyable arrays,T[N] <=> T[N]returns the same type asT's<=>and performs lexicographical elementwise comparison. There is no<=>for other arrays.
  • Forvoidthere is no<=>.
  • 对于bool、整型和指针类型,<=>返回strong_ordering
  • 对于指针类型,允许不同的 cv 限定和派生到基类转换来调用同构内置<=>,并且有内置异构operator<=>(T*, nullptr_t)。只有指向同一对象/分配的指针的比较才是常量表达式。
  • 对于基本浮点类型,<=>返回partial_ordering,并且可以被非均相通过加宽参数较大的浮点类型调用。
  • 对于枚举,<=>返回与枚举的基础类型的<=>.
  • 对于nullptr_t<=>返回strong_ordering并始终产生equal
  • 对于可复制数组,T[N] <=> T[N]返回与T's相同的类型<=>并执行按字典顺序的元素比较。<=>其他数组没有。
  • 因为void没有<=>.

To better understand the inner workings of this operator, please read the original paper. This is just what I've found out using search engines.

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

回答by msc

This is called the three-way comparisonoperator.

这称为三向比较运算符

According to the P0515paper proposal:

根据P0515论文提案:

There's a new three-way comparison operator, <=>. The expression a <=> breturns an object that compares <0if a < b, compares >0if a > b, and compares ==0if aand bare equal/equivalent.

To write all comparisons for your type, just write operator<=>that returns the appropriate category type:

  • Return an _orderingif your type naturally supports <, and we'll efficiently generate <, >, <=, >=, ==, and !=; otherwise return an _equality, and we'll efficiently generate ==and !=.

  • Return strong if for your type a == bimplies f(a) == f(b)(substitutability, where f reads only comparison-salient state accessible using the nonprivate const interface), otherwise return weak.

有一个新的三向比较运算符,<=>. 该表达式a <=> b返回一个对象,该对象比较<0if a < b、比较>0ifa > b并比较==0ifabis equal/equivalent。

要为您的类型编写所有比较,只需编写operator<=>返回适当的类别类型:

  • 返回的_ordering如果你的类型自然地支持<,我们将有效地产生<><=>===,和!=; 否则返回_equality,我们将有效地生成 ==!=

  • 如果为您的类型a == b暗示f(a) == f(b)(可替代性,其中 f 仅读取使用非私有 const 接口可访问的比较显着状态),则返回强,否则返回弱。

The cppreferencesays:

cppreference说:

The three-way comparison operator expressions have the form

lhs <=> rhs   (1)  

The expression returns an object that

  • compares <0if lhs < rhs
  • compares >0if lhs > rhs
  • and compares ==0if lhsand rhsare equal/equivalent.

三向比较运算符表达式的形式为

lhs <=> rhs   (1)  

该表达式返回一个对象,该对象

  • 比较<0如果lhs < rhs
  • 比较>0如果lhs > rhs
  • 和比较==0,如果lhsrhs是相等的/当量。

回答by Stig Hemmer

This answer has become irrelevant since the referenced web page has changed

由于引用的网页已更改,此答案已变得无关紧要

The web page you are referencingwas broken. It was being edited a lot that day and different parts was not in sync. The status when I was looking at it was:

您所引用网页已损坏。那天被编辑了很多,不同的部分不同步。我看的时候的状态是:

At the top of the page it lists the currently existing comparison operators (in C++14). There is no <=>there.

在页面顶部,它列出了当前存在的比较运算符(在 C++14 中)。那里没有<=>

At the bottom of the page, they should have listed the same operators, but they goofed and added this future suggestion.

在页面底部,他们应该列出相同的运营商,但他们搞砸了并添加了这个未来的建议。

gccdoesn't know about <=>yet (and with -std=c++14, never will), so it thinks you meant a <= > b. This is explains the error message.

gcc还不知道<=>(并且-std=c++14永远不会知道),所以它认为你的意思是a <= > b. 这是对错误消息的解释。

If you try the same thing five years from now you will probably get a better error message, something like <=> not part of C++14.

如果五年后你尝试同样的事情,你可能会得到更好的错误信息,比如 <=> not part of C++14.