Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I use the spaceship operator in a switch statement

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

#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

(live example)

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?

>Solution :

The spaceship operator returns a std::strong_ordering which is not an integral type and therefore cannot be used in a switch-case statement.

You can use it in an if-else statement instead.

If you prefer to use a switch-case, you can use a trivial utility that converts the std::strong_ordering to an integral type with some predefined values.
Returning -1/0/1 in this case will be quite natural:

#include <iostream>

constexpr int strong_ordering_to_int(std::strong_ordering o)
{
    if (o == std::strong_ordering::less)    return -1;
    if (o == std::strong_ordering::greater) return 1;
    return 0;
}

void compare_values(int x, int y)
{
    switch (strong_ordering_to_int(x <=> y))
    {
    case -1:
        std::cout << "is less\n";
        break;
    case 1:
        std::cout << "is greater\n";
        break;
    case 0:
        std::cout << "is equal\n";
        break;
    }
}

int main()
{
    compare_values(2, 3);
    compare_values(3, 2);
    compare_values(3, 3);
}

Output:

is less
is greater
is equal

Live demo

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading