【发布时间】:2016-10-06 03:24:17
【问题描述】:
我正在尝试找到一个与 constexpr 兼容的哈希函数,用于在编译时对字符串进行哈希处理。字符串的数量非常少(
static constexpr unsigned int Fnv1aBasis = 0x811C9DC5;
static constexpr unsigned int Fnv1aPrime = 0x01000193;
constexpr unsigned int hashFnv1a(const char *s, unsigned int h = Fnv1aBasis)
{
return !*s ? h : hashFnv1a(s + 1, (h ^ *s) * Fnv1aPrime);
}
但是当我在 MSVS 2015 中编译它时,我收到以下警告:
warning C4307: '*': integral constant overflow
由于函数中只有一个乘法,我假设警告来自(h ^ *s) * Fnv1aPrime。这是有道理的,因为将0x811C9DC5 (Fnv1aBasis) 乘以几乎任何东西都会导致 32 位整数溢出。
有没有办法解决这个问题?我已经尝试了其他几个用于散列字符串的 constexpr 函数,但它们都有相同的问题。
【问题讨论】:
-
您是否尝试将类型更改为
unsigned long long? -
考虑使用
uint32_t代替int(unsigned int可能是 16 位)。char可以是signed或unsigned,如果signed可以是1的补码。 -
我可以将其更改为
unsigned long long,但由于它对字符串中的每个字符进行乘法运算,因此只有在字符串足够短时才会起作用。如果我真的想要一个 64 位哈希(除非我要使用一些 128 位整数),它也行不通。我希望字符串的编译时散列是 constexpr 的一个非常常见的用例,但我看不出如果溢出触发警告它会如何工作,因为这么多散列算法依赖于溢出。 -
试试
(h ^ (static_cast<unsigned int>(*s))
标签: c++ c++11 visual-studio-2015 constexpr