为什么要使用三向比较运算符(<=>)而不是双向比较运算符?这有优势吗?

#include <compare>
#include <iostream>

int main()
{ 
   auto comp1 = 1.1 <=> 2.2;
   auto comp2 = -1 <=> 1;
   std::cout << typeid(comp1).name()<<"n"<<typeid(comp2).name();
}

输出:

结构 std::partial_ordering
结构 std::strong_ordering

我知道如果操作数具有整数类型,则运算符将返回一个 prvalue 类型std::strong_ordering。我也知道操作数是否有浮点类型,运算符会产生类型的纯右值std::partial_ordering

但是为什么我应该使用三向比较运算符而不是双向运算符(==, !=, <, <=, >, >=)?这对我有什么好处吗?

回答

它可以 在一次操作中确定顺序
其他运算符需要进行两次比较。

其他运营商的总结:

  • 如果a == b是假的,你不知道是否a < ba > b
  • 如果a != b是真的,你不知道是否a < ba > b
  • 如果a < b是假的,你不知道是否a == ba > b
  • 如果a > b是假的,你不知道是否a == ba < b
  • 如果a <= b是真的,你不知道是否a == ba < b
  • 如果a >= b是真的,你不知道是否a == ba > b

一个很好的副作用是所有其他运算符都可以根据 实现<=>,并且编译器可以为您生成它们。

另一个副作用是人们可能会对<=>数学中的等价箭头的使用感到困惑,自从打字机获得这三个符号以来,它就已经如此了。
(我个人非常的恼火如何a <=> b为“truthy”当且仅当ab等价的。)


回答

主要优点(至少对我而言)是该运算符可以默认用于类,这将自动支持类的所有可能比较。IE

#include <compare>

struct foo {
    int a;
    float b;
    auto operator<=>(const foo& ) const = default;
};

// Now all operations used before are defined for you automatically!

auto f1(const foo& l, const foo& r) {
    return l < r;
}

auto f2(const foo& l, const foo& r) {
    return l > r;
}

auto f3(const foo& l, const foo& r) {
    return l == r;
}

auto f4(const foo& l, const foo& r) {
    return l >= r;
}

auto f5(const foo& l, const foo& r) {
    return l <= r;
}

auto f6(const foo& l, const foo& r) {
    return l != r;
}

以前,所有这些操作都必须在类中定义,这既麻烦又容易出错——因为每当向类中添加新成员时,就必须记住重新访问这些操作。


回答

使用你自己的判断。

飞船操作员的重点不是专门用于比较对象。它的要点是允许编译器从宇宙飞船运算符中合成其他比较运算符。

如果您不需要特别回答小于、等于或大于的问题,则不需要直接调用它。使用对您有意义的运算符。

但是如果你需要让一个类型具有可比性,你只需要编写 2 个函数(宇宙飞船和相等)而不是 6 个。 在编写这样一个函数时,你可以在有问题的单个类型上使用宇宙飞船运算符(如果它们是可比的)以这样的方式)。这使得实现这些功能变得更加容易。

飞船操作员允许你做的另一件事是告诉你比较将提供什么的排序。部分,强,或其他。这在理论上可能很有用,但总体而言相当罕见。

  • ... and if spaceship is `default`ed, you don't even need to write `operator==`
  • @Scheff: Only if you `= default` it. [Types where you need to explicitly define a comparison operator usually have short-circuit versions if you only care about equality testing.](https://stackoverflow.com/a/61492875/734069) So if you user-define one, you need to user-define the other one (which you could do in terms of the spaceship easily enough).

以上是为什么要使用三向比较运算符(&lt;=&gt;)而不是双向比较运算符?这有优势吗?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>