リテラル文字列が指定されている場合はコンパイル時に文字列ハッシングを実行するクラスを実装しようとしています(実行時(this articleに基づく))。 私はxxHash(64ビット)のようにFNV-1aを使用していませんが、コンパイル時にはthis codeを使用しています。VS15はconstexprと文字列リテラルでC2975をスローします
は、ここに私の実装です:
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)
{
}
そして、それがうまく働いた... 私は見当もつかない何が問題なのか、あなたの助けをありがとう。
ありがとうございます。回避策または同様の機能を実現する別の方法がありますか? – Spacebrain
@Spacebrainコンパイル時の文字列処理ですか?あなたは手動で型をエンコードする必要があります... 'struct X {static constexpr const char * value =" hello "; }; ' – Barry
ありがとう、私はこれを解決しようとする:) – Spacebrain