编译时间字符串散列

新手上路,请多包涵

我在几个不同的地方读到使用 C++11 的新字符串文字可能可以在编译时计算字符串的哈希值。然而,似乎没有人愿意站出来说这将是可能的或如何完成。

  • 这可能吗?
  • 操作员会是什么样子?

我对这样的用例特别感兴趣。

 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 也可能是一个可行的解决方案。

原文由 deft_code 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 567
2 个回答

这有点晚了,但我成功地使用 constexpr 实现了编译时 CRC32 函数。它的问题在于,在撰写本文时,它仅适用于 GCC,而不适用于 MSVC 或 Intel 编译器。

这是代码片段:

 // 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

希望对你有帮助!

原文由 Clement JACOB 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果你有 c++17 编译器和 string_view,这变得微不足道,只需编写普通版本:

 constexpr uint32_t crc32(std::string_view str)
{
    uint32_t crc = 0xffffffff;
    for (auto c : str)
        crc = (crc >> 8) ^ crc_table[(crc ^ c) & 0xff];
    return crc ^ 0xffffffff;
}

原文由 Guillaume Gris 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题