我有一个有趣的错误,我在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
答案 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*
)作为键。