为什么我可以使用默认的 <=> 而不是用户提供的调用 ==?
Why can I invoke == with a defaulted <=> but not a user-provided one?
#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{}
无效?
飞船操作符最初的设计中,允许==
调用<=>
,但后来出于效率考虑不允许这样做(<=>
通常是一种低效的方式实施 ==
)。 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;
}
};
#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{}
无效?
飞船操作符最初的设计中,允许==
调用<=>
,但后来出于效率考虑不允许这样做(<=>
通常是一种低效的方式实施 ==
)。 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;
}
};