VS15使用constexpr和字符串文字抛出错误C2975

Spa*_*ain 3 c++ visual-c++ constexpr c++11

我正在尝试实现一个在编译时执行字符串哈希的类,如果给出了文字字符串,或者运行时(基于本文).我不是像作者那样使用FNV-1a而是使用xxHash(64bits),因为编译时计算我正在使用这段代码.

这是我的实现:

class StringHash {
public:
    class ConstCharWrapper {
    public:
        inline ConstCharWrapper( const char *Str ) : Internal(Str) {}
        const char *Internal;
    };

template <size_t N>
__forceinline StringHash( const char (&Str)[N] ) :
    m_Hash( std::integral_constant<uint64_t, xxh64::hash(Str, N-1)>::value )
{
}

inline StringHash( ConstCharWrapper Str ) :
    m_Hash( xxHash_64::Calc((const uint8_t*)Str.Internal, strlen(Str.Internal)) )
{
}

inline StringHash( const char *Str, size_t Length ) :
    m_Hash( xxHash_64::Calc((const uint8_t*)Str, Length) )
{
}

__forceinline operator uint64_t() const { return m_Hash; }

private:
    const uint64_t m_Hash;
};
Run Code Online (Sandbox Code Playgroud)

文字字符串被正确地分派给模板构造函数,但是我注意到,通过查看生成的程序集,在编译时没有完全计算散列.

所以我使用a std::integral_constant强制编译器在编译时执行它,但现在我得到了C2975错误('_Val' : invalid template argument for 'std::integral_constant', expected compile-time constant expression).

当试图找出问题所在时,我试图将一个硬编码的字符串直接放入模板构造函数中:

template <size_t N>
__forceinline StringHash( const char (&Str)[N] ) :
    m_Hash( std::integral_constant<uint64_t, xxHash_CT::h64("foobar", 6)>::value )
{
}
Run Code Online (Sandbox Code Playgroud)

它工作得很好......我不知道问题可能是什么,谢谢你的帮助.

Bar*_*rry 5

问题是,在这里:

template <size_t N>
__forceinline StringHash( const char (&Str)[N] ) :
    m_Hash( std::integral_constant<uint64_t, xxh64::hash(Str, N-1)>::value )
//                                                      ^^^^^^
{
}
Run Code Online (Sandbox Code Playgroud)

Str不是常量表达式(因为函数参数不是常量表达式),因此不能将结果hash()用作常量表达式.为了使这项工作,我们需要能够有字符串文字模板参数,这是一项正在进行的工作(P0424).

您的其他示例有效,因为它"foobar" 一个常量表达式