C++20 中的 3 因素比较算子 (<=>) 有什么好处?

What's the benefit of 3-ways comparison operator (<=>) in C++20?

提问人:Leon 提问时间:10/3/2022 最后编辑:Leon 更新时间:10/3/2022 访问量:88

问:

我知道它的语法。 我只是想知道有什么好处,或者它是否有意义。

没有它,我们必须像这样编码:

void func1(int x, int y) {
    if( x > y )
        doSomeThing();
    else if( x < y )
        doSomeElse();
    else
        explosive();
}

有了它,我们可以这样做:

void func1(int x, int y) {
    auto result = x <=> y;
    if( result > 0 )
        doSomeThing();
    else if( result < 0 )
        doSomeElse();
    else
        explosive();
}

除了返回比较结果外,我看不到此功能的任何好处。 有人说它可以使我们的代码更具可读性,但我不这么认为。 很明显,前一个例子具有更多的可读性。

至于返回结果,如下所示:

int func1(int x, int y) {
    return x <=> y;
}

看起来我们获得了更多的可读性,但我们仍然需要在某个地方使用另一个 if/else 检查值,例如在 func1 之外。

语法 比较 运算符 C++20

评论


答:

1赞 Nicol Bolas 10/3/2022 #1

我看不到此功能的任何好处。

那么你对实际发生的事情的思考就太狭隘了。

不存在直接使用来满足 s 的需要。它可以用来比较它们,但不是该功能存在的原因。<=>intint

它适用于实际具有复杂比较逻辑的类型。考虑。要知道一个字符串是否“小于”另一个字符串,您必须遍历两个字符串并比较每个字符。当你找到一个不等价的时,你就有了答案。std::string

您的代码在应用于 时会执行两次比较:一次与小于,一次与大于。问题是这样的:第一次比较已经找到了第一个不相等的字符。但第二个比较不知道它在哪里。因此,它必须从一开始就开始,进行与第一个完全相同的比较。string

对于一个答案,这比已经计算出的第一次比较要多得多。事实上,有一种非常简单的方法来计算字符串:从第一个字符串中减去第二个字符串中的相应字符。如果值为零,则它们相等。如果结果为负数,则第一个字符串较小;如果它是正数,则第一个字符串更大。<=>

哪个是...确切地说,回报是什么,不是吗?通过使用 ,您可以在一个空间内进行两个昂贵的比较;测试返回值与它们的成本无关紧要。<=><=>

您的比较逻辑越复杂,如果您需要将它们分类为小/大/等,您节省的费用就越多。<=>

还应该注意的是,处理器通常具有特殊的操作码来判断整数是负数、零数还是正数。如果我们查看 x86 程序集进行整数比较

func1(int, int):                             # @func1(int, int)
        cmp     edi, esi
        jle     .LBB0_1
        jmp     a()@PLT                       # TAILCALL
.LBB0_1:
        jge     .LBB0_2
        jmp     b()@PLT                       # TAILCALL
.LBB0_2:
        jmp     c()@PLT                       # TAILCALL

我们可以看到它只执行一次;和 指令使用比较结果。编译到同一个程序集,因此编译器完全将它们理解为同义词。cmpjlejge<=>