Почему я могу вызвать == с дефолтным <=>, но не предоставленным пользователем? - PullRequest
6 голосов
/ 05 апреля 2020
#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{}?

1 Ответ

8 голосов
/ 05 апреля 2020

В оригинальном проекте оператора космического корабля == разрешено вызывать <=>, но это позже запрещено из-за проблем эффективности (<=>, как правило, является неэффективным способом реализации ==). 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;
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...