constexpr用户定义的文字:是否允许?

时间:2017-08-07 02:53:17

标签: c++ templates template-meta-programming

我尝试在编译时使用用户定义的文字对我的字符串进行哈希处理     

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

但是我不会被允许为字符串文字运算符预先计算哈希值,因为参数中的字符串文字已经衰减为指针

1 个答案:

答案 0 :(得分:0)

您的上下文不需要constexpr,因此可以在运行时完成

printf("%i\n", "test"_hash);

你应该改为

constexpr auto test_hash = "test"_hash;
printf("%i\n", test_hash);

您观察到的是编译器的优化。