c++ - 为什么 `std::compare_three_way` 不是 `std::strict_weak_order` ?

标签 c++ c++20

用 C++20 的概念和三向比较,我做了我自己的 Map像这样:

template<
    typename TKey,
    typename TValue,
    std::strict_weak_order<TKey, TKey> KeyComparer = std::compare_three_way, // Error: template constraint not satisfied
    typename PairAllocator = std::allocator<KeyValuePair<TKey, TValue>>
>class SortedMap
SortedMap初始化,失败,错误 template constraint not satisfied .
修改 std::strict_weak_ordertypename那么就可以了。 (错误肯定会出现在这里。)

为什么不std::compare_three_way满足 std::strict_weak_order ?

最佳答案

std::strict_weak_order<R, T, U>需要 R成为谓词 - 调用 R在类型对象上 TU给你bool .但是std::compare_three_way不返回 bool ,它返回作为 <=> 结果的比较类别之一。 (例如 std::strong_ordering )。
标准库中目前没有关于 if 是否是返回比较类别的可调用的概念(与 strict_weak_order 是使用 < 的概念概括相同)。
所以要么:

  • 您可以在三向比较的基础上构建 map ,并相应地执行所有操作。这意味着为三向比较对象编写您自己的概念。这样的事情会做:

  • template <typename T, typename Cat>
    concept compares_as = std::same_as<std::common_comparison_category_t<T, Cat>, Cat>;
    
    template <typename R, typename T, typename U>
    concept three_way_order = std::regular_invocable<R, T, U>
      && compares_as<std::invoke_result_t<R, T, U>, std::weak_ordering>;
    
    这将拒绝部分订单 - 这意味着您不能拥有 double作为一个键(或者更确切地说,不能直接使用 <=> 作为比较,用户必须提供一个自定义比较函数来拒绝 NaN 或一些类似的东西)。如果你想直接在你的容器中处理偏单,改std::weak_orderingstd::partial_ordering以上。
    或者
  • 您在 < 之上构建您的 map 如 std::map会,所以你会使用 std::less<>std::less<Key>作为您的默认比较类型。自 x < y可以改写为(x <=> y) < 0无论如何,这仍然会使用 <=>如果那样的话<被执行。但是在您的容器实现中,您只会得到一个双向比较结果(即 bool )而不是三向比较结果(例如 std::strong_ordering )。
  • 关于c++ - 为什么 `std::compare_three_way` 不是 `std::strict_weak_order` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65047500/

    相关文章:

    c++ - 缩小命名空间到基础

    c++ - 发出警告并编译错误警告是否违反合规性?

    c++ - 如何使用矩形绘制粗线?

    c++ - 如何在 Qt 中将 TreeView 保存为 .csv 文件?

    c++ - 提高ccache命中率

    c++ - 隐藏空基类以进行聚合初始化

    c++ - 静态链接的 xerces 3.0.0 在 Linux 上动态工作时不起作用

    c++ - 如何测试 member 在概念上是否完整?

    c++ - 如何将 std::condition_variable 与我自己的互斥体包装器一起使用

    c++ - 如何使用标准跨度进行边界检查?