将operator<=>
添加到C ++ 20中,我想尝试推理如何在不是简单的成员比较的情况下实现此运算符。
您如何实施太空船运营商,以便将optional<T>
与optional<U>
或U
进行比较,我们要么必须将T
与U
进行比较{{1}}或比较基础状态,获得正确的返回类型? latest paper中没有这样的例子。
答案 0 :(得分:8)
我认为实现这一目标的正确方法是使用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;
}
};
三向bool
比较产生std::strong_ordering
,可隐式转换为其他四个比较类别。
同样,strong_ordering::less
可隐式转换为weak_ordering::less
,partial_ordering::less
,strong_equality::unequal
或weak_equality::nonequivalent
,视情况而定。