7
#include <compare>

struct A
{
    int n;
    auto operator <=>(const A&) const noexcept = default;
};

struct B
{
    int n;
    auto operator <=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};

int main()
{
    A{} == A{}; // ok
    B{} == B{}; // error: invalid operands to binary expression
}

用 clang-10 编译为clang -std=c++20 -stdlib=libc++ main.cpp

为什么A{} == A{}有效但无效B{} == B{}

4

1 回答 1

9

在 spaceship operator 的原始设计中,==允许调用<=>,但后来由于效率问题而不允许调用(<=>通常是一种低效的实现方式==)。 operator<=>() = default为方便起见,仍被定义为隐式定义operator==,它正确调用==而不是<=>成员。所以你想要的是这样的:

struct A {
    int n;
    auto operator<=>(const A& rhs) const noexcept = default;
};

// ^^^ basically expands to vvv

struct B {
    int n;
    bool operator==(const B& rhs) const noexcept
    {
        return n == rhs.n;
    }
    auto operator<=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};

请注意,您可以独立默认operator==,同时仍提供用户定义的operator<=>

struct B {
    int n;
    // note: return type for defaulted equality comparison operator
    //       must be 'bool', not 'auto'
    bool operator==(const B& rhs) const noexcept = default;
    auto operator<=>(const B& rhs) const noexcept
    {
        return n <=> rhs.n;
    }
};
于 2020-04-05T08:30:34.270 回答