为什么std库没有对std::hash<const std::string>
进行特化?
这会导致编译错误,例如:
std::unordered_map<const std::string, int> m;
m.insert(std::make_pair("Foo", 1)); //error
m["Bar"] = 2; // also error
这是有什么原因吗?
std::unordered_map<std::string, int> m;
尽管 key_type
是 std::string
,但实际上键的类型是 const std::string
,可以通过 decltype(m)::value_type::first_type
访问。
当你考虑哈希的概念时,键应该不会被更改,因此 std::hash 的特化看起来比 std::hash 更合适。你同意吗?
确保散列表函数不会且不应该更改密钥,但同时,它可能不应该复制,那为什么不使用 std::hash<const T&>
?
需要注意的一件事是,要特化的类型并不总是等于参数类型。模板参数更多地涉及到散列表函数相关的类型,而不是传递给调用运算符的类型。类似地,numeric_limits<T>
期望类型 T
为非 cv 限定的数值类型。这并不意味着 const int
和 const double
没有各自的极限值。除非您期望在 hash<T>
和 hash<const T>
上产生不同的行为,否则为什么要对它们进行两次特化?
还有一件要注意的事情是,std::hash
实际上更像是与 unordered_XXX
家族一起捆绑的实用程序类,主要用作默认情况下无序家族的哈希函数,或者用于为您的自定义类型定义自定义哈希函数以供提供给无序家族。
T
总是可以隐式转换为const T
,但反过来则不成立。 - Mark Ransom