使用unordered_map和数组作为键

Using an unordered_map with arrays as keys

本文关键字:数组 unordered map 使用      更新时间:2023-10-16

我不明白为什么我不能将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;
     ^

数组不符合钥匙,因为它们错过了一些要求?

您必须实现哈希。哈希表取决于哈希键,找到一个放入它们的水桶。C 并不神奇地知道如何放置每种类型,在这种特殊情况下,它不知道如何默认使用3个整数放置3个整数。您可以实现这样的简单哈希结构:

struct ArrayHasher {
    std::size_t operator()(const std::array<int, 3>& a) const {
        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组合到BOOST为此目的使用的功能:http://wwwww.boost.org/doc/doc/libs/1_35_0/doc/doc/html/boost/boost/boost/hash_combine_combine_id2410131311313113131311313113113.html。这应该足够强大以实际使用。

为什么?

如http://www.cplusplus.com/reference/unordered_map/unordered_map/

在内部,unordered_map中的元素均未在任何中排序 有关其密钥或映射值的特定顺序, 但根据其哈希值而组织成桶以允许 通过其关键值直接快速访问单个元素(使用 平均平均时间复杂性恒定)。

现在根据您的问题,我们需要hash尚未在标准C 中实现的数组。

如何克服它?

因此,如果要将array映射到值,则必须实现自己的std :: hath http://en.cppreference.com/w/cpp/utility/hash,您可能会从C 中获得一些帮助将数组插入哈希集中?

有些围绕

如果您可以自由使用boost,则可以为您提供数组和许多其他类型的散列。它基本上使用hash_combine方法,您可以查看http://www.boost.org/doc/libs/1_49_0/boost/functional/hash/hash/hash.hpp.

相关错误是

error: no match for call to '(const std::hash<std::array<int, 3ul> >) (const std::array<int, 3ul>&)'

unordered_map需要密钥的哈希,它寻找std::hash的超载来做到这一点。您可以使用合适的哈希功能扩展namespace std

用MSVC14编译的错误:

" C 标准不能为此类型提供哈希。"

我想这是不言自明的。