简体   繁体   中英

custom hash function for pair of enum values used as unordered_map key

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 .

您的operator()方法应为const:

std::size_t operator()(const ShapePair &pair) const

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM