The Spaceship Operator and Its Importance for Class Types in Non-Type Template Parameters

The spaceship operator coming in C++20 was first proposed as a means to simplify the overloading of comparison operators for a specific class. Undoubtedly, it fulfilled its goal as it drastically shortened the code needed to describe each comparison operator(==, !=, <, <=, >, >=).

//Previous C++ code
struct Foo
  int x;
  friend bool operator==(Foo const& foo1, Foo const& foo2) 
  { return foo1.x == return foo2.x; }
  friend bool operator!=(Foo const& foo1, Foo const& foo2) 
  { return !(foo1 == foo2); }
  friend bool operator< (Foo const& foo1, Foo const& foo2) 
  { return foo1.x < foo2.x; }
  friend bool operator<=(Foo const& foo1, Foo const& foo2) 
  { return !(foo2 < foo1); }
  friend bool operator> (Foo const& foo1, Foo const& foo2)
  { return foo2 < foo1; }
  friend bool operator>=(Foo const& foo1, Foo const& foo2) 
  { return !(foo1 < foo2); }

//C++20 Code
struct Foo
  int x;
  auto operator<=>(Foo const&) = default;

This new language feature takes advantage of automatic generation; effectively creating the needed comparison operators without any issues. An important thing to note is that the spaceship operator returns five possible types: std::strong_ordering, std::weak_ordering, std::partial_ordering, std::strong_equality, and std::weak_equality. Each of which follow the following models:

Model Return Type Operators
Total orderstd::strong_ordering==, !=, <, <=, >, >=
Weak orderstd::weak_ordering==, !=, <, <=, >, >=
Partial orderstd::partial_ordering==, !=, <, <=, >, >=
Equality comparabestd::strong_equality==, !=
Equivalence comparablestd::weak_equality==, !=

Beyond the clear gains in conciseness, the three-way comparison operator provides a new solution to the existing irregularities for class types in non-type template type parameters; an idea that wasn’t expected by the creator of the spaceship operator proposal(Herb Sutter). The problem with non-type template type parameters is that they currently only accept a small subset of types consisting of integral types, enum types, pointer types, pointer-to-member types, reference types, and std::nullptr_t; which in turn causes an inconsistency in the language by separating the use of certain types for no concrete reason. Removing this inconsistency became apparently hard, until the proposal for the spaceship operator came into fruition.

Integrating the spaceship operator to the language would guarantee equality for different instantiations of a templated entity; effectively letting custom types to be accepted as template type parameters by ensuring the following:

  • The class type has a comparison operator.

  • The class type has the same comparison operator available in all translation units.

  • The class implements member-wise equality.


The spaceship operator not only reduces the code needed to overload comparison operators as it also provides a clear solution to the inconsistencies related to class types in non-type template parameters. For further reading into this topic read the spaceship operator proposal as well as the class types in non-type template parameters proposal.