Consider this code:
#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()
{
B a;
B b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
std::cout<< (a==b);
std::cout<< (a!=b);
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
class C {
public:
bool b = {};
int v1 = {};
int v2 = {};
std::strong_ordering operator<=> (C const& r) const
{
return (b?v1:v2) <=> (r.b?r.v1:r.v2);
}
bool operator== (C const& r) const
{
return std::is_eq(*this<=>r);
}
};
void TestC()
{
C a;
C b;
std::cout<< (a<b);
std::cout<< (a>b);
std::cout<< (a<=b);
std::cout<< (a>=b);
std::cout<< (a==b);
std::cout<< (a!=b);
std::cout<< std::is_eq(a<=>b);
std::cout<< std::is_neq(a<=>b) << std::endl;
}
int main()
{
TestA();
TestB();
TestC();
return 0;
}
https://wandbox.org/permlink/SLmLZOc18RaJV7Mu
Remove comments to get an error.
First I want to ask why default three-way operator behaves differently than user define operator?
And second, is the solution to this problem correct for class C
or should it be handled differently?
This is just a simple example and I have more complex situation in mind with tens of fields and unions (If you don't know what I mean, check out some Intel APIs ;) ).
Edit:
This question Equality operator does not get defined for a custom spaceship operator implementation in C++20 focused on why there is no default equality operator for user defined 3-way operator, I would like to know why there is a difference in default and user define behavior?
Edit 2:
I slightly modified class C
in the example to picture more of real life problem (when default operators are not valid solution). I also want to clarify that I would like to known the reasons behind those differences (between user define and default operator) to be able to assess if my real life solution is correct (similar to C
) as I do value more code maintainability than performance for a part of code that I am working right now.
==
with a defaulted<=>
?”, which doesn’t seem useful. – Cherellecheremis