There's a new comparison operator <=>
in C++20. However I think in most cases a simple subtraction works well:
int my_strcmp(const char *a, const char *b) {
while (*a == *b && *a != 0 && *b != 0) {
a++, b++;
}
// Version 1
return *a - *b;
// Version 2
return *a <=> *b;
// Version 3
return ((*a > *b) - (*a < *b));
}
They have the same effect. I can't really understand the difference.
The operator solves the problem with numeric overflow that you get with subtraction: if you subtract a large positive number from a negative that is close to
INT_MIN
, you get a number that cannot be represented as anint
, thus causing undefined behavior.Although version 3 is free from this problem, it utterly lacks readability: it would take some time to understand by someone who has never seen this trick before.
<=>
operator fixes the readability problem, too.This is only one problem addressed by the new operator. Section 2.2.3 of Herb Sutter's Consistent comparison paper talks about the use of
<=>
with other data types of the language where subtraction may produce inconsistent results.There are some meaningful answers here on the difference, but Herb Sutter in his paper specifically says:
So even if there was no difference, the point of the operator is different: to aid class writers to generate comparison operators.
The core difference between the subtraction operator and the "spaceship" operator (according to Sutter's proposal) is that overloading
operator-
gives you a subtraction operator, whereas overloadingoperator<=>
:default
: no code to write!);Other differences are in the return value:
operator<=>
would return anenum
of a class, the class specifies whether the type is sortable and whether the sort is strong or weak. The return value would convert to -1, 0 or 1 (though Sutter leaves room for the return type to also indicate distance, asstrcmp
does). In any case, assuming the -1, 0, 1 return value, we'll finally get a true signum function in C++! (signum(x) == x<=>0
)Here are some cases that subtraction won't work for:
unsigned
types.operator -
(perhaps because it's not meaningful - one may define an order without defining a notion of distance).I suspect this list is non-exhaustive.
Of course, one can come up with workarounds for at least #1 and #2. But the intent of
operator <=>
is to encapsulate that ugliness.