2017-12-14 21 views
3

리터럴 문자열 또는 다른 주어진 런타임 (this article 기준) 경우 컴파일 타임에 문자열 해시 수행하는 클래스를 구현하는 중입니다. 필자가 작성한 것처럼 FNV-1a를 사용하고 있지는 않지만 xxHash (64 비트), 컴파일 시간 계산에 나는 this code을 사용하고 있습니다.VS15 constexpr 및 문자열 리터럴 함께 오류 C2975 throw합니다

여기 내 구현의 :

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; 
}; 

리터럴 문자열이 제대로 템플릿 생성자에 파견하지만 해시가 완전히 컴파일 시간에 계산되지 않았 음을, 생성 된 어셈블리를보고,났습니다.

그래서 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) 
{ 
} 

그리고 그냥 괜찮 았는데 ... 나는 단서가 없다 문제가 무엇이 될지, 당신의 도움에 감사드립니다.

답변

5

문제는 여기에있다 : (함수의 매개 변수가없는 상수 표현이기 때문에) 당신이 상수 표현으로 hash()의 결과를 사용할 수 있도록

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

Str

는 상수 표현하지 않습니다 . 이 작업을 수행하기 위해 진행중인 작업 인 문자열 리터럴 템플릿 매개 변수를 가질 수 있어야합니다 ( P0424).

다른 예제는 상수 표현이므로 작동합니다.

+0

감사합니다. 유사한 해결 방법을 얻는 방법이나 다른 방법이 있습니까? – Spacebrain

+1

@Spacebrain 컴파일 시간 문자열 처리? 당신은 수동으로 타입을 인코딩해야 할 것입니다 ...'struct X {static constexpr const char * value = "hello"; }; ' – Barry

+0

고마워, 나는 이것을 해결하려고 노력할 것이다. :) – Spacebrain