当前位置: 首页 > 知识库问答 >
问题:

C++中的(“spaceship”,三向比较)运算符是什么?

荆利
2023-03-14

当我试图学习C++运算符的时候,我无意中在cppreference.com上发现了一个奇怪的比较运算符,*在如下表中:

“好吧,如果这些是C++中常见的运算符,我最好学会它们”,我想。但我想要弄清楚这个谜团的一切努力都没有成功。即使在这里,在堆栈溢出,我没有运气在我的搜索。

如果有的话,这个运算符到底是做什么的?

*同时CPPreference.com更新了该页,现在包含有关<=>运算符的信息。

共有3个答案

汝才良
2023-03-14

由于所引用的网页已更改,此答案已变得不相关

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

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

在页面的底部,他们本应该列出相同的操作员,但他们笨手笨脚地加上了这个未来的建议。

gcc还不知道<=>(对于-std=C++14,永远不会知道),因此它认为您指的是A<=>B。这是对错误消息的解释。

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

山煜祺
2023-03-14

在2017-11-11日,ISO C++委员会通过了Herb Sutter关于<=>“宇宙飞船”三向比较运算符的建议,作为C++20中增加的新特性之一。在题为一致性比较的论文中,Sutter,Maurer和Brown演示了新设计的概念。关于该建议的概述,本文摘录如下:

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

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

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

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

  • 如果您的类型自然支持<,则返回一个_ordering,并且我们将高效地生成对称的<,>,<=,>=,==,和!=;否则返回_equality,我们将高效地生成对称的==和!=.
  • 返回strong_if对于您的类型a==b意味着f(a)==f(b)(可替换性,其中f只读取可使用公共常量成员访问的比较显著状态),否则返回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 |             |
+------------------+------+------------+---------------+-------------+

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

    值为{ lessequalgreater}的
  • strong_ordering隐式转换为:
    • weak_ordering值{较小等效较大}
    • Partial_Ordering值{较小等效较大}
    • strong_equality值{unequal,equal,unequal}
    • weak_equality值{非等价,等价,非等价}
    • Partial_Ordering值{较小等效较大}
    • weak_equality值{非等价,等价,非等价}
    • weak_equality值{非等价,等价,非等价,非等价,非等价}
    • weak_equality值{等价非等价}

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

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

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

    • 对于bool、integral和pointer类型,<=>返回strong_ordering
    • 对于指针类型,允许不同的CV限定和派生到基的转换调用同构的内置<=>,并且存在内置的异构运算符<=>(t*,nullptr_t)。只有指向相同对象/分配的指针的比较才是常量表达式。
    • 对于基本浮点类型,<=>返回partial_ordering,并且可以通过将参数扩大到更大的浮点类型来进行异构调用。
    • 对于枚举,<=>返回与枚举的基础类型的<=>相同的值。
    • 对于nullptr_t<=>返回strong_ordering并始终生成equal
    • 对于可复制数组,t[N]<=>t[N]返回与t<=>相同的类型,并执行词典式元素比较。其他数组没有<=>
    • 对于void没有<=>

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

晁开宇
2023-03-14

这称为三向比较运算符。

根据P0515论文建议:

有一个新的三元比较运算符<=>。表达式A<=>B返回一个对象,如果A 比较 <0;如果 A>B比较 0;如果 AB相等/等价,则比较 ==0

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

>

  • 如果您的类型自然支持<,则返回an_ordering,并且我们将高效地生成<<=====!=;否则返回_equality,我们将高效地生成==和!=。

    如果对于您的类型a==b暗示f(a)==f(b)(可替换性,其中f仅读取使用非私有常量接口可访问的比较显著状态),则返回strong,否则返回weag。

    cppreference表示:

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

    lhs <=> rhs   (1)  
    

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

    • 比较<0如果lhs
    • 比较>0如果LHS>RHS
    • 如果LHSRHS相等/等价,则比较==0

  •  类似资料:
    • 问题内容: 将在今年11月发布的PHP 7将引入Spaceship(<=>)运算符。它是什么以及它如何工作? 问题答案: 该(“飞船”),运营商将提供,它会合并比较: 组合比较运算符使用的规则与PHP viz当前使用的比较运算符相同。,,,和。那些来自Perl或Ruby编程背景的人可能已经熟悉为PHP7建议的这个新运算符。

    • 我知道,如果操作数为整型,运算符将返回类型的prvalue。我还知道,如果操作数是浮点类型,运算符将生成类型的prvalue。 但是为什么要使用三方比较运算符而不是双向运算符(,,,,,)?这会给我带来什么好处吗?

    • 本文向大家介绍c#中的三元运算符是?相关面试题,主要包含被问及c#中的三元运算符是?时的应答技巧和注意事项,需要的朋友参考一下 三元运算符,有的也称三目运算符,是对if else  双分支条件语句的简化 格式如下: 表达式一?表达式二:表达式三        释义:如果表达式一为真,就执行问号后边紧跟着的表达式,也就是表达式二;             否则执行冒号后边的表达式,即表达式三。 等价

    • 问题内容: 稍微打错一下就遇到了这个问题(在Python 2.7.5中): 当它,我不小心爆炸了月亮。 我的理解是相当于和表现良好的类(如内置函数),相当于。 如果没有或运算符,那么我认为Python使用。 但是,这些方法都与工作对象,而与运营商 做 的工作。发生这种情况的原因是什么? 问题答案: 但是,当<和>运算符起作用时,这些方法都不能与函数对象一起起作用。发生这种情况的原因是什么? 在任何

    • 概述 比较运算符用于比较两个值的大小,然后返回一个布尔值,表示是否满足指定的条件。 2 > 1 // true 上面代码比较2是否大于1,返回true。 注意,比较运算符可以比较各种类型的值,不仅仅是数值。 JavaScript 一共提供了8个比较运算符。 > 大于运算符 < 小于运算符 <= 小于或等于运算符 >= 大于或等于运算符 == 相等运算符 === 严格相等运算符 != 不相等运算符

    • 本文向大家介绍Elixir比较运算符,包括了Elixir比较运算符的使用技巧和注意事项,需要的朋友参考一下 示例 平等: 价值平等x == y(1 == 1.0 # true) 价值不平等x == y(1 != 1.0 # false) 严格平等x === y(1 === 1.0 # false) 严格不等式x === y(1 !== 1.0 # true) 比较: x > y x >= y x