【发布时间】:2017-08-07 02:53:17
【问题描述】:
我正在尝试在编译时使用用户定义的文字对我的字符串进行哈希处理
constexpr unsigned int const_hash(char const *input) {
return *input ?
static_cast<unsigned int>(*input) + 33 * const_hash(input + 1) :
5381;
}
constexpr unsigned int operator ""_hash (const char *input, size_t) {
return const_hash(input);
}
int main(void) {
printf("%i\n", "test"_hash);
return 0;
}
它适用于 GCC
mov esi, 2090770981
mov edi, OFFSET FLAT:.LC0
xor eax, eax
call printf
但不在 MSVC 中
push OFFSET ??_C@_04CEJDCDCH@test?$AA@+1
call ?const_hash@@YAIPBD@Z
mov ecx, eax
add eax, 116 ; 00000074H
shl ecx, 5
add eax, ecx
push eax
push OFFSET ??_C@_03PELOGHMK@?$CFi?6?$AA@
call _printf
add esp, 12 ; 0000000cH
所以我猜 constexpr 用户定义的文字是一个 UB/编译器实现?是否在 FDIS 中指定?
(我知道递归 constexpr 函数是不允许的,但我以它为例)
编辑:
这是一个 FNV-1 非递归的:http://godbolt.org/g/KF9BaE
这里又是一个 DJB2 非递归的:http://godbolt.org/g/7eJmpp
我可以通过安装模板来强制执行恒定的哈希行为: http://godbolt.org/g/fsuFS9
但是我将不允许预先评估字符串文字运算符的哈希,因为参数中的字符串文字已经衰减为指针
【问题讨论】:
-
"我知道递归 constexpr 函数是不允许的,但我以它为例" 你有没有想过这可能是它不起作用的原因,而不是您正在使用 UDL 的事实?将
constexpr函数不能做的事情用作测试似乎是有问题的,UDL 与否。 -
不,我尝试了各种 constexpr C++ 哈希函数,包括 crc32、fnv1、djb2、递归和非递归,它们都具有相似的行为。
-
我这里使用的 constexpr 哈希函数是 djb2 的变种。
-
然后提供一个非递归的例子。
-
question 中包含相关信息,而不是下面的 cmets。随意编辑您的问题并将这些内容添加到其中。
标签: c++ templates template-meta-programming