如何为key创建一个哈希函数,作为在unordered_map中使用的字符串和枚举对?
我有以下这对无序地图的关键如何创建一个哈希,以便在unordered_map中使用?
enum Color {
Red,
Green
};
typedef std::pair <std::string, Color>
我尝试了以下内容但遇到了编译错误
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
size_t hash( const PairType & pair ) {
return std::hash<std::string>()(pair.first) ^
std::hash<EnumClassHash>()(pair.second);
}
typedef std::unordered_map<PairType, std::string>,
std::function<decltype(hash)>> ColorMapType;
error: invalid use of incomplete type 'struct std::hash<EnumClassHash>'
std::hash<EnumClassHash>()(pairType.second);
以下不起作用
size_t hash( const PairType & pairType ) {
return std::hash<std::string>()(pairType.first) ^
std::hash<Color>()(pairType.second);
}
typedef std::unordered_map<PairType, std::string, \
std::function<decltype(hash)>> ColorMapType;
ColorMapType colorMap(100, hash);
error: invalid use of incomplete type 'struct std::hash<Color>'
std::hash<Color>()(pair.second
);
PS Pardon我的格式化。我丢失了我的Gmail密码,只能从一个小屏幕的移动应用程序发布。答案 0 :(得分:2)
struct EnumClassHash
时,这是它自己的事情,而不是std::hash
的专业化。std::hash<EnumClassHash>()(pair.second)
时,模板专精std::hash<EnumClassHash>
根本就不存在。你可以:
struct EnumClassHash
,并使用EnumClassHash
或std::hash
专门化为std::hash<Color>
,并使用std::hash<Color>
或但从不混合和匹配每种方法的一部分,这没有任何意义。
此外,要使用std::pair<std::string, Color>
作为std::unordered_map
的关键类型,std::hash<Color>
和EnumClassHash
都不重要。重要的是std::hash<std::pair<std::string, Color>>
或您自己的哈希std::pair<std::string, Color>
。
这是您可以遵循的食谱。
要使用std::pair<std::string, Color>
作为键类型,您需要自己专门设置std::hash<std::pair<std::string, Color>>
。
template <>
struct std::hash<std::pair<std::string, Color>>
{
std::size_t operator()(const std::pair<std::string, Color>& p) const {
return std::hash<std::string>()(p.first) ^ std::hash<Color>()(p.second);
}
};
但在此之前,您需要首先专注std::hash<Color>
,因为std::hash<std::pair<std::string, Color>>
使用它。
template <>
struct std::hash<Color>
{
std::size_t operator()(Color c) const {
return static_cast<size_t>(c);
}
};
然后,您可以使用std::unordered_map<std::pair<std::string, Color>, std::string>
之类的内容。没有EnumClassHash
参与。
如果你非常喜欢EnumClassHash
,这是另一个方法。
您可以随意保留EnumClassHash
。
struct EnumClassHash
{
template <typename T>
std::size_t operator()(T t) const
{
return static_cast<std::size_t>(t);
}
};
这一次,std::hash<Color>
不存在。不要使用它。 (更不用说没有意义的std::hash<EnumClassHash>
。)
因此,散列键类型的类应该使用EnumClassHash
。 (再一次,不是std::hash<EnumClassHash>
!)
struct PairHash {
std::size_t operator()(const std::pair<std::string, Color>& p) const {
return std::hash<std::string>()(p.first) ^ EnumClassHash()(p.second);
}
};
现在,您可以使用std::unordered_map<std::pair<std::string, Color>, std::string, PairHash>
。