为什么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
有什么原因吗?
发布于 2021-11-20 22:40:01
为什么
std::hash<const std::string>
不是专门研究性病的?
事实上,性病并没有专门针对任何std::hash<const T>
。原因可能是它不需要。对于任何std::hash<T>
,它唯一的函数是一个operator()
,它接受const T&
作为它的参数。因此,即使std::hash<const Foo>
是专门化的,它也将与std::hash<Foo>
完全相同。
然后再回到您所困扰的代码,它实际上应该是:
std::unordered_map<std::string, int> m;
在这里,尽管key_type
是std::string
,但是键的实际类型实际上是const std::string
,它可以用decltype(m)::value_type::first_type
访问。
更新:
当您想到哈希的概念时,键不应该被更改,所以std::散列的特殊化看起来比std::散列更合适。你不同意吗?
确保哈希函数不会也不应该更改键,但是在同一时间,它可能不应该接受副本,那么为什么不使用std::hash<const T&>
呢?
需要注意的一点是,专门化的类型并不总是等于参数类型。模板参数更多地是关于与哈希函数相关的类型,而不是传递给调用运算符的类型。类似地,numeric_limits<T>
期望非cv限定数字类型为T
类型。这并不意味着const int
和const double
没有各自的限制。除非您期望在hash<T>
和hash<const T>
上有不同的行为,那么为什么要对它们进行两次专门化呢?
另外要注意的是,std::hash
实际上更像是一个与unordered_XXX
家族捆绑在一起的实用程序类,它主要用作无序家族的哈希函数,或者用于为您的定制类型定义您的自定义哈希函数,以便将其提供给无序家族。
https://stackoverflow.com/questions/70052270
复制