#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
#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
}
Run Code Online (Sandbox Code Playgroud)
用 clang-10 编译为 clang -std=c++20 -stdlib=libc++ main.cpp
为什么A{} == A{}有效但无效B{} == B{}?
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) 考虑这个代码:
#include <iostream>
#include <compare>
class A {
public:
int i = {};
std::strong_ordering operator<=> (A const& r) const
{
return i <=> r.i;
}
};
void TestA()
{
A a;
A b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
//std::cout<< (a==b); //ERROR
std::cout << 'E';
//std::cout<< (a!=b); //ERROR
std::cout << 'E';
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
class B {
public:
int i = {};
std::strong_ordering operator<=> (B const& r) const = default;
};
void TestB()
{ …Run Code Online (Sandbox Code Playgroud)