如何专门针对除size_t以外的返回类型使用std :: hash调用运算符?

时间:2019-03-20 16:03:04

标签: c++ hashtable c++17

这是我第一次尝试使用c ++ 17 std::unordered_map。我正在尝试构建一个快速的LRU,将sha1摘要映射到数据块。我的sha1对象是完全可比的,等等,但是当我尝试实例化地图时,出现此错误:

/usr/include/c++/7/bits/hashtable_policy.h:87:34: error: no match for call to ‘(const std::hash<
kbs::crypto::basic_digest<20,kbs::crypto::openssl_sha1_digest_engine_policy> >) (const kbs::crypto::basic_digest<20, kbs::crypto::openssl_sha1_digest_engine_policy>&)’
  noexcept(declval<const _Hash&>()(declval<const _Key&>()))>

因此,看来我可以为用户定义的类型专门设置std::hash。但是,它总是返回size_t,这很糟糕,从20字节变为8字节有点违反了将sha1用作hash_key的目的。

是否有解决此问题的方法?替代容器?不得不编写自己的哈希图是一种浪费。我想我可以使用std:set ...

1 个答案:

答案 0 :(得分:4)

无序映射不假定哈希(size_t)是唯一的。它假设键是。如果散列为,则效果很好。

无序映射使用size_t确定将数据放入哪个存储桶。它可以很好地处理size_t空间中的冲突。

根据需要将sha哈希映射到size_t,并使用sha哈希作为密钥。在极少数情况下,您会遇到size_t哈希冲突(假设无序列表中大约有40亿个元素,则假设哈希良好,则为50/50-数学上请参见“生日悖论”,或更常见的情况是哈希表较小) ;它会动态地扩展表格),它将依赖于您的sha哈希键的相等性来避免“真正的”冲突。

有多种冲突。

  • 哈希哈希冲突:不好,意味着相同的密钥具有不同的数据。
  • size_t哈希冲突:meh,这意味着两个元素将始终位于同一存储桶中。
  • 内部哈希表冲突:常见,表示在此特定大小下,两个元素位于同一存储桶中。

除非您的大多数数据都使用相同的size_t,否则该映射有损是完全可以的。您只需要担心第一种冲突,然后在哈希中提供==