如果我std::hash
使用libstdc++
然后在即将推出的C++11
VS 2012 库中使用,它们会匹配吗?
我假设哈希实现不是 C++ 规范的一部分,并且可能因分布而异?
不,这不能保证。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 ()。
标准只这么说:
20.8.12 类模板散列 23.5 中定义的无序关联容器使用类模板散列的特化作为默认散列函数。对于存在专门化散列的所有对象类型 Key,实例化散列应:
- 满足 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 是 hash 类型的对象,k1 和 k2 是 Key 类型的对象。
在 17.6.3.4 中,这是最重要的(表 26):
不得抛出异常。返回的值应仅取决于参数 k。[ 注意:因此,对于具有相同 k 值的表达式 h(k) 的所有评估都会产生相同的结果。— end note ] [ 注意:对于两个不同的值 t1 和 t2,h(t1) 和 h(t2) 比较相等的概率应该很小,接近 1.0 / numeric_-limits::max()。——尾注]
所以一般来说,不,计算本身没有定义,结果不需要在实现上保持一致。就此而言,即使是同一个库的两个不同版本也可能给出不同的结果。
函数返回值的要求(17.6.3.4 Hash requirements [hash.requirements]Hash
)是:
表 26 - 哈希要求 [哈希]
返回的值应仅取决于参数
k
。h(k)
[注意:因此,对具有相同值的表达式的所有评估都会k
产生相同的结果。——尾注] [注:对于两个不同的值t1
和t2
,h(t1)
和h(t2)
比较相等的概率应该很小,接近1.0 / numeric_limits<size_t>::max()
。——尾注]
std::hash(k)
在实践中,对于整数类型而言,equal是很常见的k
,因为这是符合标准的最简单的实现。对于其他类型,一切皆有可能。