用 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_order
至 typename
那么就可以了。 (错误肯定会出现在这里。)为什么不
std::compare_three_way
满足 std::strict_weak_order
?
最佳答案
std::strict_weak_order<R, T, U>
需要 R
成为谓词 - 调用 R
在类型对象上 T
和 U
给你bool
.但是std::compare_three_way
不返回 bool
,它返回作为 <=>
结果的比较类别之一。 (例如 std::strong_ordering
)。
标准库中目前没有关于 if 是否是返回比较类别的可调用的概念(与 strict_weak_order
是使用 <
的概念概括相同)。
所以要么:
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
以上。或者
<
之上构建您的 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/