3

可以在 C++20 中检查类型的部分排序属性吗?如果是这样,如何使用概念进行这样的检查?

以下代码是否足以达到此目的?

#include <compare>
#include <concepts>

template<class T>
concept PartialOrder = requires (const T& lhs, const T& rhs) {
  // Is there any caveat in this?
  { lhs <=> rhs } -> std::convertible_to<std::partial_ordering>;
};
4

1 回答 1

6

There already is such a concept in the standard library: three_way_comparable. T satisfies three_way_comparable if all the binary comparison operators and <=> are all valid expressions and the invocation of <=> gives you at least std::partial_ordering.

It's a little bit more involved than the one you're proposing - partially to avoid weird types (e.g. maybe some type defines operator<=> but also deletes operator<= for whatever reason? Let's just exclude those...) but also because having an ordering require equality is also pretty sensible. Just because a type is only partially ordered doesn't need it can't support == as well.

One other point is your PartialOrder<T&> actually ends up comparing non-const objects of type T, rather than const ones. Which isn't ideal. That's why the standard does this const remove_reference_t<T>& dance.

Note that neither what you're suggesting nor the standard library concept checks that a type is only partially ordered, just that it's at least partially ordered. int satisfies both std::three_way_comparable and your PartialOrder concepts, despite obviously having a total order.


One way of achieving proper subsumption with this particular concept is:

template <typename T>
concept partially_ordered = std::three_way_comparable<T>;

template <typename T>
concept totally_ordered = partially_ordered<T> &&
    requires (std::remove_cvref_t<T> const& lhs, std::remove_cvref_t<T> const& rhs) {
        { lhs <=> rhs } -> std::convertible_to<std::weak_ordering>;
    };

Or to be lazier:

template <typename T>
concept totally_ordered = partially_ordered<T> &&
    std::three_way_comparable<T, std::weak_ordering>;

Possibly by replacing weak_ordering with strong_ordering.

Also note that there is a std::totally_ordered concept - but it does not require <=>.

于 2020-05-05T02:30:06.920 回答