Реализующий оператор & lt; = & gt; для необязательного & lt; T & gt;

С operator<=> Будучи добавленным в C ++ 20, я хотел попытаться обдумать, как реализовать этот оператор для тех случаев, когда это не простое сравнение по элементам.

Как бы вы реализовали оператор космического корабля для сравнения optional<T> для optional<U>или U, это тот случай, когда мы должны сравнить T к U или сравнить базовые состояния, получая правильный тип возвращаемого значения? Там нет такого примера в последняя статья.

17

Решение

Я считаю, что правильным способом реализации этого было бы использование 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в зависимости от обстоятельств.

8

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]