The new <=> operator makes writing code more convenient and it can save some performance if the comparison algorithm is non-trivial, because it doesn't need to be repeated two times to get the full ordering.
Or at least I though so when I learned about it.
However, when I try to use it in practice, in a switch statement, it doesn't work.
This code doesn't compile:
#include <iostream>
void compare_values(int x, int y)
{
switch (x <=> y)
{
case std::strong_ordering::less:
std::cout << "is less\n";
break;
case std::strong_ordering::greater:
std::cout << "is greater\n";
break;
case std::strong_ordering::equal:
std::cout << "is equal\n";
break;
}
}
The compiler shows an error suggesting that the value returned by <=> cannot be used in a switch:
<source>: In function 'void compare_values(int, int)':
<source>:5:15: error: switch quantity not an integer
5 | switch (x <=> y)
| ~~^~~~~
Compiler returned: 1
I would guess that using the spaceship operator in switch is a pretty basic, obvious and common use case, so there is probably some trick to making it work. I cannot figure it out, though.
How can I fix this code?
The problem is that the spaceship operator (formally known as three-way comparison) does not return an ingeral type, and therefore cannot be used in a
switch-casestatement.In this case of comparing types like
ints, the spaceship operator returns astd::strong_ordering.(A side note: as you can see in the documentation there are cases where the spaceship operator returns a
std::partial_orderingbut this isn't an integral type either).You can use it in an
if-elsestatement instead.If you prefer to use a
switch-case, you can use a trivial utility that converts thestd::strong_orderingto an integral type with some predefined values.Returning -1/0/1 in this case will be quite natural:
Output:
Live demo