如果我使用std::hash
libstdc++
然后在即将到来的C++11
VS 2012图书馆中做了一个 - 它们会匹配吗?
我假设哈希实现不是C ++规范的一部分,可以根据分布而变化吗?
答案 0 :(得分:9)
不,这不能保证。 std::hash
只需遵守以下条件:
- 接受Key类型的单个参数。
- 返回size_t类型的值,该值表示参数的哈希值。
- 调用时不会抛出异常。
- 对于两个相等的参数k1和k2,std :: hash()(k1)== std :: hash()(k2)。
- 对于不相等的两个不同参数k1和k2,std :: hash()(k1)== std :: hash()(k2)的概率应该是 非常小,接近1.0 / std :: numeric_limits :: max()。
醇>
答案 1 :(得分:9)
标准只说明了这一点:
20.8.12类模板散列23.5中定义的无序关联容器使用类模板散列的特化作为 默认哈希函数。对于所有对象类型存在的键 一个特化哈希,实例化哈希应该:
- 满足Hash要求(17.6.3.4),Key为函数调用参数类型,DefaultConstructible要求(表19), CopyAssignable要求(表23),
- 对于左值,可以交换(17.6.3.2),
- 提供两个嵌套类型result_type和argument_type,它们分别是size_t和Key的同义词,
- 满足以下要求:如果k1 == k2为真,则h(k1)== h(k2)也为真,其中h是散列类型的对象,k1和k2是 Key类型的对象。
在17.6.3.4中,这是最重要的(表26):
不要抛出异常。返回的值仅取决于 论证k。 [注:因此对表达式h(k)的所有评估 使用相同的k值得到相同的结果。 - 尾注] [注: 对于两个不同的值t1和t2,h(t1)和 h(t2)比较等于应该非常小,接近1.0 / numeric_- 限制:: MAX()。 - 结束说明]
所以一般来说,不,计算本身没有定义,结果不需要在实现上保持一致。就此而言,即使同一个库的两个不同版本也可能会产生不同的结果。
答案 2 :(得分:5)
Hash
函数返回的值的要求( 17.6.3.4哈希要求[hash.requirements] )是:
表26 - 哈希要求[哈希]
返回的值仅取决于参数
k
。 [注意:因此对表达式h(k)
进行了所有评估k
的相同值产生相同的结果。 - 注意事项] [注意: 对于两个不同的值t1
和t2
,概率为。{1}}和h(t1)
h(t2)
和1.0 / numeric_limits<size_t>::max()
比较等于非常小,接近std::hash(k)
。 - 后注]
在实践中,对于整数类型k
将等于{{1}},这是很常见的,因为这是符合标准的最简单的可能实现。对于其他类型,任何事情都是可能的。