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?
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;
}