实现运算符&lt; =&gt;对于可选<t>

时间:2017-11-15 19:15:30

标签: c++ c++20 spaceship-operator

operator<=>添加到C ++ 20中,我想尝试推理如何在不是简单的成员比较的情况下实现此运算符。

您如何实施太空船运营商,以便将optional<T>optional<U>U进行比较,我们要么必须将TU进行比较{{1}}或比较基础状态,获得正确的返回类型? latest paper中没有这样的例子。

1 个答案:

答案 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::lesspartial_ordering::lessstrong_equality::unequalweak_equality::nonequivalent,视情况而定。