【问题标题】:Check if a type is a partial order检查类型是否为偏序
【发布时间】:2020-08-19 14:45:47
【问题描述】:

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

【问题讨论】:

  • 您对“偏序属性”有一个准确的定义吗?
  • 就部分排序的 C++20 current definition 而言是的。

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


【解决方案1】:

standard library中已经有了这样的概念:three_way_comparableT 满足 three_way_comparable 如果 all 二进制比较运算符和 &lt;=&gt; 都是有效的表达式,&lt;=&gt; 的调用至少给你std::partial_ordering

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

另一点是您的PartialOrder&lt;T&amp;&gt; 实际上最终比较了T 类型的非常量 对象,而不是const 的对象。这并不理想。这就是为什么标准会这样 const remove_reference_t&lt;T&gt;&amp; 跳舞。

请注意,您的建议和标准库概念都不会检查类型是否部分排序,而只是检查它是否至少部分排序。 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 概念 - 但它不需要&lt;=&gt;

【讨论】:

  • 我假设总订单包含部分订单,因此为什么要检查可兑换性而不是相同性
  • C++ 并不是唯一一个将排序和等效性放在同一页面中的人:1。从语义上讲,这似乎是一个明智的选择。
猜你喜欢
  • 2011-09-26
  • 2016-05-19
  • 2012-11-15
  • 2019-01-05
  • 1970-01-01
  • 1970-01-01
  • 2023-01-24
  • 1970-01-01
  • 2016-10-12
相关资源
最近更新 更多