适用于任何枚举类型的C++11哈希函数
C++11 Hash function for any enum type
我正在为我的对象编写一个哈希函数。我已经可以对容器进行散列,并组合散列,这要归功于所有STL容器的Generic hash函数。但是我的类也有枚举。当然,我可以为每个枚举创建一个散列函数,但这似乎不是一个好主意。是否可以为std::hash
创建一些通用规范,以便将其应用于每个枚举?类似的东西,使用std::enable_if
和std::is_enum
namespace std {
template <class E>
class hash<typename std::enable_if<std::is_enum<E>::value, E>::type> {
public:
size_t operator()( const E& e ) const {
return std::hash<std::underlying_type<E>::type>()( e );
}
};
};
PS。此代码不编译
error: template parameters not used in partial specialization:
error: ‘E’
无法推导出E
参数,因为编译器无法知道enable_if<...>::type
最终会再次表示E
(事实上,它的一些特殊化在设计上并没有做到这一点!)。它被称为E
的"非推导上下文"。
如果hash
只有一个参数,就没有办法(据我所知)对您的部分专业化进行SFINAE。
如果您愿意使用宏,可以在枚举声明旁边转储正确的std::hash专用化。
否则,我发现的唯一容易散列枚举值的方法就是泛化散列类型:
struct enum_hash
{
template <typename T>
inline
typename std::enable_if<std::is_enum<T>::value, std::size_t>::type
operator ()(T const value) const
{
return static_cast<std::size_t>(value);
}
};
并以这种方式使用:
enum class E { a, b, c };
std::unordered_map<E, std:string, enum_hash> map;
map[E::a] = "a";
标准禁止您尝试做的事情。
〔namespace.std〕
如果C++程序添加声明或命名空间std或命名空间std中的命名空间的定义除非另有规定。
程序可以为任何仅当声明取决于用户定义的类型,专业化满足原始模板的标准库要求,而不是明确禁止。
因此,您当然可以追求这些答案中的一些想法,但不能称之为std::hash。定义自己的"enum_hash"模板似乎是个好主意。
相关文章:
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 使用Qt C++计算类似Git的SHA1哈希
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- 用C++将哈希表写入文件并从文件中恢复
- c++找不到具有相同哈希的无序集合元素
- 哈希文件递归并保存到矢量Cryptopp中
- 对 pair<pair<int,int>pair<int,int unordered_map进行哈希处理>>
- 直接在 unordered_map 的方法中使用哈希,而不是生成哈希的用户定义对象
- 如何为字符串生成唯一但一致的 N 位哈希(小于 64 位)?
- 使用对象的基类部分模板专用化对对象进行哈希处理::哈希
- boost::包含提升单元的元组的哈希值
- 简单的 C++11 哈希函数无法编译
- C 11多态映射键静态断言失败:哈希函数必须与密钥类型的参数无关
- C++ concurrent_unordered_map C++11 Microsoft 使用无符号长作为密钥/哈希函数
- 在C 11中具有哈希地图结构的最直接侵略是什么
- C++旧版本(不是 C++11)-- map -> 覆盖哈希代码
- C++中是否存在哈希表(C++11之前)
- 适用于任何枚举类型的C++11哈希函数
- 用C++11对自己的String类型进行哈希