错误:未使用不完整的类型'struct std::hash<>'无效



如何为键创建一个哈希函数作为字符串和枚举对,以便在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::hashstd::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>.

最新更新