这是我第一次尝试使用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 ...
答案 0 :(得分:4)
无序映射不假定哈希(size_t
)是唯一的。它假设键是。如果散列为好,则效果很好。
无序映射使用size_t
确定将数据放入哪个存储桶。它可以很好地处理size_t
空间中的冲突。
根据需要将sha哈希映射到size_t
,并使用sha哈希作为密钥。在极少数情况下,您会遇到size_t
哈希冲突(假设无序列表中大约有40亿个元素,则假设哈希良好,则为50/50-数学上请参见“生日悖论”,或更常见的情况是哈希表较小) ;它会动态地扩展表格),它将依赖于您的sha哈希键的相等性来避免“真正的”冲突。
有多种冲突。
除非您的大多数数据都使用相同的size_t,否则该映射有损是完全可以的。您只需要担心第一种冲突,然后在哈希中提供==
。