How to copy unordered_map with a const key?
简单代码:
1 2 3 4 5 6 7 | #include <unordered_map> int main() { std::unordered_map<const int, int> m; std::unordered_map<const int, int> m1 = m; } |
生成复杂的编译错误消息:
Error C2280 'std::hash<_Kty>::hash(void)': attempting to reference a
deleted function
基本上说,
PS:我读过类似问题的答案:
The associative containers only expose the (key,value) pair as
std::pair, so the additional const on the
key type is superfluous.
但这并不能解释为什么带有const键的hashmap实际上不可用,以及如何绕过这个问题。
类型
1 | std::unordered_map<const int, int> |
使用默认的第三个参数
复制无序的存储集时需要工作哈希。要创建有效哈希,请执行以下操作:
您可以自己专门化
1 2 3 4 5 6 | namespace std { // fixes it but is a bad idea - could break in future revisions of the standard template<> struct hash<const int> : hash<int>{}; } |
或者您可以显式地声明散列:
1 | std::unordered_map<const int, int, std::hash<int>> |
或者您可以去掉密钥中的const(因为它没有效果):
1 | std::unordered_map<int, int> |
附录:
删除是指删除非专用
1 2 3 4 5 6 7 | template <typename T> struct hash { hash() = delete; hash(const hash) = delete; // more deleted methods }; |
"删除"表示它不存在(既不提供用户也不默认)。
您可以在cppreference中看到这一点,它们使用启用/禁用的术语:
For every type Key for which neither the library nor the user provides an enabled specialization std::hash, that specialization exists and is disabled.
由于
Disabled specializations do not satisfy Hash, [...] std::is_default_constructible_v, std::is_copy_constructible_v [...] are all false. In other words, they exist, but cannot be used.
因此,这些构造函数必须是不可用的(删除它们是最好的方法)。