如何为键创建一个哈希函数作为字符串和枚举对,以便在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请原谅我的格式。我丢失了Gmail密码,只能从移动应用程序发布,这是一个小屏幕。
- 当你声明
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>
.