for example, there is a structure with two fields:
struct point {
float x, y;
bool operator ==(point p) { return x == p.x && y == p.y; }
bool operator <(point p) { return x < p.x && y < p.y; }
bool operator <=(point p) { return x <= p.x && y <= p.y; }
bool operator >(point p) { return x > p.x && y > p.y; }
bool operator >=(point p) { return x >= p.x && y >= p.y; }
};
Comparison operators check the condition through logical AND for each variable, how should the <=> operator look like so that its result does not differ from these operators?
I already tried to move all operators to the new <=> back when compilers only began to support it, but neither then nor now have I found a way to implement what I wanted.
The only more or less working version of the code that I found:
std::partial_ordering operator<=> (const point& p) const {
std::partial_ordering c = x <=> point.x;
if(y <=> point.y != c) return std::partial_ordering::unordered;
return c;
}
It produces correct results for < and >, but incorrect results for <= and >=. For example, point(0, 0) <= point(0, 1)
is true
but here <=>
returns unordered
.
One of the issues with your relational comparisons is that they're not actually consistent. Namely:
bool operator ==(point p) { return x == p.x && y == p.y; }
bool operator <(point p) { return x < p.x && y < p.y; }
bool operator <=(point p) { return x <= p.x && y <= p.y; }
The definition of p <= q
is (p < q) or (p == q)
. But that's not what's actually going on here.
Considering your example where p
is (0, 0)
and q
is (0, 1)
:
p == q
is false
(they're not the same)p < q
is false
(because while p.y < q.y
, it is not the case that p.x < q.x
)Yet, nevertheless:
p <= q
is true
(because p.x <= q.x
and also p.y <= q.y
)That's inconsistent.
Your operator<=>
is actually correct, it just helped expose the fact that your operator<=
and operator>=
are incorrect.