Warm tip: This article is reproduced from serverfault.com, please click

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

(c++ - Why isn't `std::compare_three_way` a `std::strict_weak_order`?)

发布于 2020-11-28 07:45:58

通过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

Questioner
zjyhjqs
Viewed
11
Barry 2020-11-28 22:56:31

std::strict_weak_order<R, T, U>要求R是谓词-调用R类型的对象TU给你bool但是std::compare_three_way不返回bool,而是返回<=>(例如std::strong_ordering结果的比较类别之一

在标准库中,目前尚无任何概念可用于返回比较类别的可调用对象(以与usestrict_weak_order的概念概括相同的方式<)。

所以:

  1. 你可以在三向比较的基础上构建 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_ordering转到std::partial_ordering上面。

或者

  1. 你建立你之上的 map<std::map做,所以你会使用std::less<>std::less<Key>作为默认的比较类型。由于无论如何x < y都可以重写(x <=> y) < 0,因此<=>如果<实现的方式仍然可以使用但是在你的容器实现中,你只会得到bool双向比较结果(例如std::strong_ordering),而不是双向比较结果(例如)。