I'm trying to use a std::pair
of enum values as key for an unordered_map container, but I have difficulties in defining a custom hash function.
I tried the following:
// Enum and pair declaration
enum ShapeType{ PLANE, BOX, SPHERE };
typedef std::pair<ShapeType, ShapeType> ShapePair;
// unordered_map declaration
typedef void(*CollisionMethod)(const Shape*, const Shape*, CollisionData*);
typedef std::unordered_map<ShapePair, CollisionMethod, ShapePairHash> CollisionMethodsTable;
I don't understand how define correctly ShapePairHash
functor. I tried the following:
struct ShapePairHash
{
std::size_t operator()(const ShapePair &pair)
{
return std::hash<std::size_t>()(pair.first) ^ std::hash<std::size_t>()(pair.second);
}
};
but I get error C3840 (expression having type 'type' would lose some const-volatile qualifiers in order to call 'function'
)on VS compiler.
Can anyone suggest me the right way to declare a custom hash function to be used with unordered_map
?
You can define a last enum value, and then use it to generate the hash (actually a perfect hash). Note that this assume that the number of possible enum values is low enough so that (suppose that the number of enum values is N): N * N + N < MAX_UINT
enum class ShapeType : unsigned int { PLANE = 0, BOX = 1, SPHERE = 2, LAST = 3 };
struct ShapePairHash
{
std::size_t operator()(const ShapePair &pair) const
{
return static_cast<std::size_t>(pair.first)
* static_cast<std::size_t>(ShapeType::LAST)
+ static_cast<std::size_t>(pair.second)
}
};
Also, for your compilation problem you just need to declare the function const.