c++qtc++20return-type-deductionspaceship-operator

Three-way comparison operator with inconsistent ordering deduction


Some time ago I defined my first three-way comparison operator. It compared a single type and replaced multiple conventional operators. Great feature. Then I tried to implement a similar operator for comparing two variants by delegation:

auto operator <=> (const QVariant& l, const QVariant& r)
{   
   switch (l.type())
   {
      case QMetaType::Int:
         return l.toInt() <=> r.toInt();
      case QMetaType::Double:
         return l.toDouble() <=> r.toDouble();
      default:
         throw;
   }
}

This doesn't compile, I get the error

inconsistent deduction for auto return type: ‘std::strong_ordering’ and then ‘std::partial_ordering’.

Obviously int and double spaceship operators return different types.

What is the correct way to solve this?


Solution

  • The types of the operator<=> for int and double differ but they should have a common type. You probably want to leverage the compiler in automatically finding the proper type. You could use std::common_type to do but that would be quite ugly. It is easier to just leverage what std::common_type type does under the (when implemented in the library rather the compiler) and use the ternary operator:

    auto operator <=> (const QVariant& l, const QVariant& r)
    {   
        return l.type() == QMetaType:Int? l.toInt() <=> r.toInt()
             : l.type() == QMetaType::Double? l.toDouble() <=> r.toDouble()
             : throw;
    }