什么是< =>(C ++)中的(“太空飞船",三向比较)运算符? [英] What is the <=> ("spaceship", three-way comparison) operator in C++?

查看:67
本文介绍了什么是< =>(C ++)中的(“太空飞船",三向比较)运算符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试学习 C ++ 运算符时,我偶然发现了,ISO C ++委员会采用了草药Sutter 关于< =>宇宙飞船"三向比较运算符的建议,作为添加到 C ++ 20 的新功能之一.在标题为一致比较萨特的论文中,Maurer和Brown演示了新设计的概念.有关提案的概述,请参见以下文章的摘录:

表达式 a< => b 返回一个对象,该对象比较< 0 (如果 a<b ,如果 a> b ,则比较> 0 ,如果a和b是,则比较 == 0 相等/等效.

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

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

高级案例:要写出类型为 X 和类型为 Y 的所有比较,只需编写 operator <=> Y 的strong> = default 以获得成员语义(如果需要),并返回适当的类别类型:

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

比较类别

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

  + -------------------------------------------------------------------- +||数值|非数字||类别+ ----------------------------------- + |||-1 |0 |+1 |价值观|+ ------------------ + ------ + ------------ + --------------- + ------------- +|strong_ordering |少|等于|更大|||weak_ordering |少|等价更大|||局部排序|少|等价更大|无序||strong_equality ||等于|不等|||弱平等||等价不等价||+ ------------------ + ------ + ------------ + --------------- + ------------- + 

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

    值{ less 等于更大}的
  • strong_ordering 隐式转换为:
    • 弱排序的值为{ less 等效更大}
    • partial_ordering 的值为{ less equivalent greater }
    • strong_equality 的值为{ unqual equal unqual }
    • 弱等式,其值为{ nonequivalent equivalent nonequivalent }
  • 值为{ less equivalent greater }的
  • weak_ordering 隐式转换为:
    • partial_ordering 的值为{ less equivalent greater }
    • 弱等式,其值为{ nonequivalent equivalent nonequivalent }
  • partial_ordering 的值为{ less equivalent greater unordered }隐式转换为:
    • 弱等式,其值为{ nonequivalent equivalent nonequivalent nonequivalent }
  • 值为{ equal unqual }的
  • strong_equality 隐式转换为:
    • 弱等式,其值为{ equivalent nonequivalent }

三向比较

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

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

对于语言类型,提供了以下内置的< => 相同类型的比较.除非另有说明,否则均为 constexpr .这些比较不能使用标量提升/转换来异构调用.

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

为更好地了解此操作符的内部工作原理,请阅读原始内容cppreference.com,* in a table that looked like this:

"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.

Is there a connection between <=> and 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.

解决方案

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

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

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

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

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

  • Return an _ordering if 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 == b implies f(a) == f(b) (substitutability, where f reads only comparison-salient state that is accessible using the public const members), otherwise return weak_.

Comparison Categories

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

+--------------------------------------------------------------------+
|                  |          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_ordering with values {less, equal, greater} implicitly converts to:
    • weak_ordering with values {less, equivalent, greater}
    • partial_ordering with values {less, equivalent, greater}
    • strong_equality with values {unequal, equal, unequal}
    • weak_equality with values {nonequivalent, equivalent, nonequivalent}
  • weak_ordering with values {less, equivalent, greater} implicitly converts to:
    • partial_ordering with values {less, equivalent, greater}
    • weak_equality with values {nonequivalent, equivalent, nonequivalent}
  • partial_ordering with values {less, equivalent, greater, unordered} implicitly converts to:
    • weak_equality with values {nonequivalent, equivalent, nonequivalent, nonequivalent}
  • strong_equality with values {equal, unequal} implicitly converts to:
    • weak_equality with values {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.

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.

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.

  • 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<=>.

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.

这篇关于什么是&lt; =&gt;(C ++)中的(“太空飞船",三向比较)运算符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆