我正在尝试使用std :: pair枚举值作为unordered_map容器的键,但是我在定义自定义散列函数时遇到了困难。
我尝试了以下内容:
//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;
我不明白如何正确定义ShapePairHash仿函数。我尝试了以下方法:
struct ShapePairHash
{
std::size_t operator()(const ShapePair &pair)
{
return std::hash<std::size_t>()(pair.first) ^ std::hash<std::size_t>()(pair.second);
}
};
但我在VS编译器上收到错误C3840(expression having type 'type' would lose some const-volatile qualifiers in order to call 'function'
)。
有人能建议我使用unordered_map来声明自定义哈希函数的正确方法吗?
答案 0 :(得分:3)
您可以定义最后一个枚举值,然后使用它来生成散列(实际上是一个完美的散列)。请注意,这假设可能的枚举值的数量足够低,以便(假设枚举值的数量为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)
}
};
另外,对于编译问题,您只需要声明函数 const 。
答案 1 :(得分:2)
你的operator()方法应该是const:
std::size_t operator()(const ShapePair &pair) const