#include <compare>
struct A
{
int n;
auto operator<=>(A const& other) const
{
if (n < other.n)
{
return std::strong_ordering::less;
}
else if (n > other.n)
{
return std::strong_ordering::greater;
}
else
{
return std::strong_ordering::equal;
}
}
// compile error if the following code is commented out.
// bool operator==(A const& other) const
// { return n == other.n; }
};
int main()
{
A{} == A{};
}
Run Code Online (Sandbox Code Playgroud)
看在线演示
为什么我必须 operator == 在 足够的时候提供operator <=> ?
c++ language-design language-lawyer spaceship-operator c++20
我<=>在C ++ 20中使用新的宇宙飞船运算符遇到一种奇怪的行为。我正在将Visual Studio 2019编译器与一起使用/std:c++latest。
这段代码可以正常编译:
#include <compare>
struct X
{
int Dummy = 0;
auto operator<=>(const X&) const = default; // Default implementation
};
int main()
{
X a, b;
a == b; // OK!
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,如果我将X更改为:
struct X
{
int Dummy = 0;
auto operator<=>(const X& other) const
{
return Dummy <=> other.Dummy;
}
};
Run Code Online (Sandbox Code Playgroud)
我收到以下编译器错误:
error C2676: binary '==': 'X' does not define this operator or a conversion to …
#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();
}
Run Code Online (Sandbox Code Playgroud)
输出:
结构 std::partial_ordering
结构 std::strong_ordering
我知道如果操作数具有整数类型,则运算符将返回一个 prvalue 类型std::strong_ordering。我也知道操作数是否有浮点类型,运算符会产生类型的纯右值std::partial_ordering。
但是为什么我应该使用三向比较运算符而不是双向运算符(==, !=, <, <=, >, >=)?这对我有什么好处吗?
C++20 引入了新的太空船运算符<=>,它允许根据三向比较的排序强度来合成相等和比较运算符。
然而,当使用以下简单的玩具示例执行异构比较时,它似乎无法合成相等运算符 - 但仍然成功合成排序运算符 - 尽管具有std::strong_ordering:
#include <compare>
#include <cassert>
template <typename T>
struct Wrapper {
int value;
auto operator<=>(const Wrapper&) const = default;
template <typename U>
auto operator<=>(const Wrapper<U>& other) const {
return value <=> other.value;
}
};
void test() {
// Same type equality -- works
assert(Wrapper<Foo>{42} == Wrapper<Foo>{42});
// Heterogeneous comparison -- works
assert(Wrapper<Foo>{42} < Wrapper<Bar>{45});
// Heterogeneous equality -- doesn't work?
assert(Wrapper<Foo>{42} == Wrapper<Bar>{42});
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 上,这会出现以下错误:
<source>: In function …Run Code Online (Sandbox Code Playgroud)