C++20 Comparison Operators – Advantages of Using Three-Way (<=>) Over Two-Way

c++c++20comparison-operatorsspaceship-operator

#include <compare>
#include <iostream>

int main()
{ 
   auto comp1 = 1.1 <=> 2.2;
   auto comp2 = -1 <=> 1;
   std::cout << typeid(comp1).name()<<"\n"<<typeid(comp2).name();
}

Output:

struct std::partial_ordering
struct std::strong_ordering

I know that if the operands have an integral type, the operator returns a PRvalue of type std::strong_ordering. I also know if the operands have a floating-point type, the operator yields a PRvalue of type std::partial_ordering.

But why should I use a three-way comparison operator instead of two-way operators (==, !=, <, <=, >, >=)? Is there an advantage this gives me?

Best Answer

It makes it possible to determine the ordering in one operation.
The other operators require two comparisons.

Summary of the other operators:

  • If a == b is false, you don't know whether a < b or a > b
  • If a != b is true, you don't know whether a < b or a > b
  • If a < b is false, you don't know whether a == b or a > b
  • If a > b is false, you don't know whether a == b or a < b
  • If a <= b is true, you don't know whether a == b or a < b
  • If a >= b is true, you don't know whether a == b or a > b

A neat side effect is that all the other operators can be implemented in terms of <=>, and a compiler can generate them for you.

Another side effect is that people might be confused by the use of <=> as the equivalence arrow in mathematics, which it has been pretty much since typewriters got those three symbols.
(I'm personally pretty miffed by how a <=> b is "truthy" if and only if a and b are not equivalent.)