未为 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*
) 作为键。
我在使用自定义 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*
) 作为键。