我不明白为什么我不能拥有unordered_map
作为密钥类型array<int,3>
:
#include <unordered_map>
using namespace std;
int main() {
array<int,3> key = {0,1,2};
unordered_map< array<int,3> , int > test;
test[key] = 2;
return 0;
}
我得到一个很长的错误,最相关的部分是
main.cpp:11:9: error: no match for ‘operator[]’ (operand types are std::unordered_map<std::array<int, 3ul>, int>’ and ‘std::array<int, 3ul>’)
test[key] = 2;
^
数组是否有资格成为密钥,因为它们错过了一些要求?
答案 0 :(得分:8)
相关错误是
error: no match for call to '(const std::hash<std::array<int, 3ul> >) (const std::array<int, 3ul>&)'
unordered_map
需要密钥的哈希值,并且它会查找std::hash
的重载来执行此操作。您可以使用合适的哈希函数扩展namespace std
。
答案 1 :(得分:8)
<强>为什么吗
正如http://www.cplusplus.com/reference/unordered_map/unordered_map/
中所述在内部,unordered_map中的元素未按任何方式排序 关于其键值或映射值的特定顺序, 但是根据它们的哈希值组织成桶以允许 通过键值快速访问各个元素(使用 平均时间复杂度恒定。)
现在根据你的问题,我们需要hash
一个尚未在标准c ++内部实现的数组。
如何克服它?
因此,如果您想将array
映射到某个值,则必须实现自己的std :: hash http://en.cppreference.com/w/cpp/utility/hash,您可以从C++ how to insert array into hash set?获得一些帮助。
有些解决方法
如果您可以自由使用boost
,那么它可以为您提供数组和许多其他类型的散列。它基本上使用hash_combine
方法,您可以查看http://www.boost.org/doc/libs/1_49_0/boost/functional/hash/hash.hpp。
答案 2 :(得分:8)
您必须实现哈希。散列表取决于散列键,找到一个存储桶.C ++并不神奇地知道如何散列每个类型,在这种特殊情况下,它不知道如何默认散列3个整数的数组。您可以实现这样的简单哈希结构:
struct ArrayHasher {
std::size_t operator()(const std::array<int, 3>& a) {
std::size_t h = 0;
for (auto e : a) {
h ^= std::hash<int>{}(e) + 0x9e3779b9 + (h << 6) + (h >> 2);
}
return h;
}
};
然后使用它:
unordered_map< array<int,3> , int, ArrayHasher > test;
编辑:我更改了将来自天真xor的哈希值与为此目的使用的函数组合的函数:http://www.boost.org/doc/libs/1_35_0/doc/html/boost/hash_combine_id241013.html。这应该足够强大,可以实际使用。
答案 3 :(得分:2)
使用msvc14编译时出现以下错误:
&#34; C ++标准没有为此类型提供哈希值。&#34;
我想这是不言自明的。