Compile time string hashing(编译时字符串散列)
问题描述
我在几个不同的地方读到,使用 C++11 的新字符串文字可能可以在编译时计算字符串的哈希值.然而,似乎没有人准备好站出来说这将是可能的或将如何完成.
I have read in few different places that using C++11's new string literals it might be possible to compute a string's hash at compile time. However, no one seems to be ready to come out and say that it will be possible or how it would be done.
- 这可能吗?
- 操作员会是什么样子?
我对这样的用例特别感兴趣.
I'm particularly interested use cases like this.
void foo( const std::string& value )
{
switch( std::hash(value) )
{
case "one"_hash: one(); break;
case "two"_hash: two(); break;
/*many more cases*/
default: other(); break;
}
}
注意:编译时哈希函数不必与我编写的完全一样.我尽力猜测最终的解决方案会是什么样子,但 meta_hash<"string"_meta>::value 也可能是一个可行的解决方案.
Note: the compile time hash function doesn't have to look exactly as I've written it. I did my best to guess what the final solution would look like, but meta_hash<"string"_meta>::value could also be a viable solution.
推荐答案
这有点晚了,但我成功地使用 constexpr 实现了编译时 CRC32 函数.它的问题在于,在撰写本文时,它仅适用于 GCC,不适用于 MSVC 或 Intel 编译器.
This is a little bit late, but I succeeded in implementing a compile-time CRC32 function with the use of constexpr. The problem with it is that at the time of writing, it only works with GCC and not MSVC nor Intel compiler.
这是代码片段:
// CRC32 Table (zlib polynomial)
static constexpr uint32_t crc_table[256] = {
0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
...
};
template<size_t idx>
constexpr uint32_t crc32(const char * str)
{
return (crc32<idx-1>(str) >> 8) ^ crc_table[(crc32<idx-1>(str) ^ str[idx]) & 0x000000FF];
}
// This is the stop-recursion function
template<>
constexpr uint32_t crc32<size_t(-1)>(const char * str)
{
return 0xFFFFFFFF;
}
// This doesn't take into account the nul char
#define COMPILE_TIME_CRC32_STR(x) (crc32<sizeof(x) - 2>(x) ^ 0xFFFFFFFF)
enum TestEnum
{
CrcVal01 = COMPILE_TIME_CRC32_STR("stack-overflow"),
};
CrcVal01 等于 0x335CC04A
CrcVal01 is equal to 0x335CC04A
希望对你有帮助!
这篇关于编译时字符串散列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:编译时字符串散列
基础教程推荐
- GDB 显示调用堆栈上函数地址的当前编译二进制文 2022-09-05
- 非静态 const 成员,不能使用默认赋值运算符 2022-10-09
- 为什么派生模板类不能访问基模板类的标识符? 2021-01-01
- 为什么 RegOpenKeyEx() 在 Vista 64 位上返回错误代码 2021-01-01
- CString 到 char* 2021-01-01
- 通过引用传递 C++ 迭代器有什么问题? 2022-01-01
- 为什么 typeid.name() 使用 GCC 返回奇怪的字符以及如 2022-09-16
- 我应该对 C++ 中的成员变量和函数参数使用相同的名称吗? 2021-01-01
- 如果我为无符号变量分配负值会发生什么? 2022-01-01
- 初始化列表*参数*评估顺序 2021-01-01
