С operator<=>
Будучи добавленным в C ++ 20, я хотел попытаться обдумать, как реализовать этот оператор для тех случаев, когда это не простое сравнение по элементам.
Как бы вы реализовали оператор космического корабля для сравнения optional<T>
для optional<U>
или U
, это тот случай, когда мы должны сравнить T
к U
или сравнить базовые состояния, получая правильный тип возвращаемого значения? Там нет такого примера в последняя статья.
Я считаю, что правильным способом реализации этого было бы использование std::compare_3way()
Шаблон функции для обработки (1) жизнеспособности такого сравнения и (2) категории сравнения.
Это делает реализацию всех операторов сравнения достаточно компактной:
template <typename T>
class optional {
public:
// ...
template <typename U>
constexpr auto operator<=>(optional<U> const& rhs) const
-> decltype(compare_3way(**this, *rhs))
{
if (has_value() && rhs) {
return compare_3way(**this, *rhs);
} else {
return has_value() <=> rhs.has_value();
}
}
template <typename U>
constexpr auto operator<=>(U const& rhs) const
-> decltype(compare_3way(**this, rhs))
{
if (has_value()) {
return compare_3way(**this, rhs);
} else {
return strong_ordering::less;
}
}
constexpr strong_ordering operator<=>(nullopt_t ) const {
return has_value() ? strong_ordering::greater
: strong_ordering::equal;
}
};
3-х сторонний bool
сравнение дает std::strong_ordering
, который неявно конвертируется в другие четыре категории сравнения.
Точно так же, strong_ordering::less
будучи неявно конвертируемым в weak_ordering::less
, partial_ordering::less
, strong_equality::unequal
, или же weak_equality::nonequivalent
в зависимости от обстоятельств.
Других решений пока нет …