compile-time string hashing

前端 未结 4 498

I need to use a string as the ID to obtain some object. At implement this in a run-time, and works well. But this makes the static type checking impossible, for obvious rea

相关标签:
4条回答
  • 2020-12-31 10:25

    I don't know of a way to do this with the preprocessor or with templates. I suspect your best bet is to create a separate pre-compile step (say with perl or such) to generate the hash_cstring statements from a set of source statements. Then at least you don't have to split the strings manually when you add new ones, and the generation is fully automated and repeatable.

    0 讨论(0)
  • 2020-12-31 10:29

    In case anyone is interested, I walk through how to create a compile time hash of Murmur3_32 using C++11 constexpr functions and variadic templates here:

    http://roartindon.blogspot.sg/2014/10/compile-time-murmur-hash-in-c.html

    Most of the examples I've seen deal with hashes that are based on consuming one character of the string at a time. The Murmur3_32 hash is a bit more interesting in that it consumes 4 characters at a time and needs some special case code to handle the remaining 0, 1, 2 or 3 bytes.

    0 讨论(0)
  • 2020-12-31 10:34

    Templates can be instantiated with any external symbol, therefore this should work as expected:

    external char const* object_method = "object.method";
    ... = hash_cstring<object_method>::value;
    

    (given the template hash_cstring<> is able to deal with pointer values).

    0 讨论(0)
  • 2020-12-31 10:38

    Solution with gcc-4.6:

    #include <iostream>
    template<size_t N, size_t I=0>
    struct hash_calc {
        static constexpr size_t apply (const char (&s)[N]) {
           return  (hash_calc<N, I+1>::apply(s) ^ s[I]) * 16777619u;
        };
    };
    
    template<size_t N>
    struct hash_calc<N,N> {
        static constexpr size_t apply (const char (&s)[N]) {
           return  2166136261u;
        };
    };
    
    template<size_t N>
    constexpr size_t hash ( const char (&s)[N] ) {
        return hash_calc<N>::apply(s);
    }
    
    int main() {
       char a[] = "12345678";
       std::cout << std::hex << hash(a) << std::endl;
       std::cout << std::hex << hash("12345678") << std::endl;
    }
    

    http://liveworkspace.org/code/DPObf

    I`m happy!

    0 讨论(0)
提交回复
热议问题