检查类型是否为偏序

Check if a type is a partial order

可以在 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>;
};

standard library中已经有这样的概念:three_way_comparableT 满足 three_way_comparable 如果 所有 二元比较运算符和 <=> 都是有效的表达式并且 <=> 的调用至少给你std::partial_ordering.

它比您提议的要复杂一些 - 部分是为了避免奇怪的类型(例如,也许某些类型定义了 operator<=> 但也出于某种原因删除了 operator<=?让我们排除那些...) 但也因为排序要求相等也是非常明智的。仅仅因为一个类型只是部分排序不需要它也不能支持 ==

还有一点是您的 PartialOrder<T&> 实际上最终比较的是 非常量 类型 T 对象,而不是 const 对象。这并不理想。这就是标准 const remove_reference_t<T>& 跳舞的原因。

请注意,您的建议和标准库概念都不会检查类型是否 部分排序,只是 至少 部分订购。 int 满足 std::three_way_comparable 和您的 PartialOrder 概念,尽管显然有总顺序。


使用此特定概念实现适当包含的一种方法是:

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>;
    };

或者更懒惰:

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

可能会将 weak_ordering 替换为 strong_ordering

另请注意,有一个 std::totally_ordered 概念 - 但它不需要 <=>