哈希没有为类引用定义?

时间:2015-12-28 02:19:12

标签: c++ c++11 unordered-map

我有一个有趣的错误,我在std::unordered_map中使用自定义类作为键。我已经为这个自定义类实现了一个哈希函数。

如果我创建一个std::unordered_map,那么一切运行正常:

std::unordered_map <Component, int> myMap;

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

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

错误3错误C2338:C ++标准没有为此类型提供哈希。

知道如何才能让它发挥作用吗?

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

1 个答案:

答案 0 :(得分:3)

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

要解决您的问题,您应该查看std::reference_wrapper,它能够在对象中包装引用,然后代码将成为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*)作为键。