如何在带有来自 std::string 的 unordered_map 的字符串文字上使用 is_transparent 功能?
Posted
技术标签:
【中文标题】如何在带有来自 std::string 的 unordered_map 的字符串文字上使用 is_transparent 功能?【英文标题】:How to use is_transparent feature on a string literal with unordered_map from std::string? 【发布时间】:2013-12-03 12:09:30 【问题描述】:在 cppreference 上环顾四周,我发现 std::unordered_map
gets efficient lookup 的功能来自“等效键”。
我认为这意味着等效键必须具有相同的哈希值。我如何才能为字符串文字提供与 std::hash<std::string>
相同的哈希值,而无需临时构造 std::string
从而使等效键的全部意义无效?
【问题讨论】:
乍一看,我发现有 2 个问题需要克服:1) 查找(以及其他std::unordered_map
查找函数)都采用 Key const&
,这将立即创建一个临时函数。 2) 字符串文字没有 std::hash
特化。我怀疑最好的答案是编写自己的容器,它类似于unordered_map
,但允许按字符串文字进行搜索,并使用可以处理std::string
(存储值)以及const char*
的自定义散列函数用于查找。
@DaveS 那么为什么 cppreference 说从 C++14 开始的 unordered_map
对 find
有一个“等效键”的重载?我很困惑。我认为在open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3657.htm 上介绍is_transparent
的论文似乎没有为散列函数对象介绍它。另外,cppreference 谈到的Compare
是什么?我觉得我错过了一些重要的东西。我只是觉得很臭,即使在 C++14 中,我仍然需要为这些简单的问题编写自己的容器:(
是的,这个想法是您编写自己的哈希函数来涵盖所有等效类型。对于这个用例,无论如何我总是有一些“pairstd::hash
在 C++14 中获得了这种支持吗?您链接的论文仅显示在关联容器上,而不是无序容器上。尽管 cppreference 具有所有优点,但它还大量使用内部模板来减少重复。似乎map
和unordered_map
都在使用相同的find
描述块,这解释了Compare::is_transparent
在描述中的使用。
【参考方案1】:
这是 cppreference 中的错误;对于无序的关联容器没有模板化查找。
比较,来自 n3690,
来自§23.5.4.1[unord.map.overview]
// lookup
iterator find(const key_type& k);
const_iterator find(const key_type& k) const;
size_type count(const key_type& k) const;
来自§23.4.4.1[map.overview]
// 23.4.4.5, map operations:
iterator find(const key_type& x);
const_iterator find(const key_type& x) const;
template <class K> iterator find(const K& x);
template <class K> const_iterator find(const K& x) const;
size_type count(const key_type& x) const;
【讨论】:
如果他们也添加无序关联容器就好了。它需要一个透明的KeyEqual
函数,还需要一个Hash
,它支持Key 类型和模板化find
的输入。我认为指定后者会有点棘手。
@DaveS for unordered_set< T, Hash, Equal >
, 如果Hash::is_transparent
添加unordered_set< T, Hash, Equal >::find<K>(const K& x)
执行Hash(x)
然后Equal( y, x )
其中y
是由Hash(x)
找到的元素?现在,x
必须是 Equal
-able(通过转换或透明度),但是...【参考方案2】:
正如其他人所说,无序关联容器不支持is_transparent
模式。另一方面,Boost.MultiIndex 散列索引允许您想要的,如documentation 中所述,如果您可以选择用基于multi_index_container
的等效结构替换std::unordered_map
。
【讨论】:
【参考方案3】:无序容器的异构查找已被 C++20 采用(p0919、p1690)。它已经在gcc
11.0 和clang
12.0 中可用。
【讨论】:
以上是关于如何在带有来自 std::string 的 unordered_map 的字符串文字上使用 is_transparent 功能?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用参数将 std::string 复制到 std::string?
真的没有来自 std::string_view 的 std::string 的显式构造函数吗?