未为 Class 引用定义哈希?

Hash Not Defined for Class Reference?

我在使用自定义 class 作为 std::unordered_map 中的键时发生了一个有趣的错误。我已经为这个自定义 class.

实现了一个哈希函数

如果我创建一个 std::unordered_map 这样一切都运行良好:

std::unordered_map <Component, int> myMap;

但是,如果我创建一个 std::unordered_map,其中键是引用,它会抱怨没有为此类型实现的哈希函数:

std::unordered_map <Component&, int> myMap; 

Error 3 error C2338: The C++ Standard doesn't provide a hash for this type.

知道如何让它工作吗?

class Component
{
public:
    GUID id;

    Component()
    { 
        generateGUID(&id);
    }

    bool operator== (const Component& other) const
    {
        return compareGUID(id, other.id);
    }
};

namespace std
{
    template<>
    struct hash<Component>
    {
        std::size_t operator()(const Component& cmp) const
        {
            using std::size_t;
            using std::hash;

            return hash<GUID>()(cmp.id); // GUID hash has also been implemented
        }
    };
}


std::unordered_map<Component, int> cMap1;  // compiles ok
std::unordered_map<Component&, int> cMap2;  // causes compiler error

问题不在于如何正确覆盖 Component& 的散列。问题是 STL 容器是用来存储对象的,而引用不是对象。请注意,术语 object 包括基元和指针,因为它们需要存储,而引用则不需要。

要解决您的问题,您应该查看 std::reference_wrapper, which is able to wrap a reference inside an object, then the code would become something like:

#include <iostream>
#include <unordered_map>
#include <functional>

using namespace std;

struct Component
{
    size_t id;
};

namespace std
{
    template<>
    struct hash<reference_wrapper<Component>>
    {
        size_t operator()(const reference_wrapper<Component>& cmp) const
        {
            return cmp.get().id;
        }
    };
}

unordered_map<reference_wrapper<Component>, int> mapping;

如果你不想使用 reference_wrapper 那么你应该使用指针 (Component*) 作为键。