简体   繁体   English

编译时字符串哈希

[英]compile-time string hashing

I need to use a string as the ID to obtain some object. 我需要使用一个字符串作为ID来获取一些对象。 At implement this in a run-time, and works well. 在运行时实现这一点,并且运行良好。 But this makes the static type checking impossible, for obvious reasons. 但由于显而易见的原因,这使得静态类型检查变得不可能。

I've Googled for the algorithm for calculating the hash-sum of string in the compile-time: C++ compile-time string hashing with Boost.MPL . 我用Google搜索了在编译时计算字符串的哈希和的算法:使用Boost.MPL进行C ++编译时字符串哈希处理

It seems to be the perfect solution to my problem, except that the sring which is necessary to the algorithm should be split into pieces by 4 characters, or character-by-character, as well, for obvious reasons. 它似乎是我的问题的完美解决方案,除了算法所必需的sring应该被分成4个字符或逐个字符,显而易见的原因。

ie, instead of the usual current record of the ID's, I'll have to write this way: 即,而不是通常的ID的当前记录,我将不得不这样写:

hash_cstring<boost::mpl::string<'obje', 'ct.m', 'etho', 'd'>>::value

This is absolutely unusable. 这绝对无法使用。

The question is, how to pass correctly the string such as "object.method" to this algorithm? 问题是,如何正确地将诸如"object.method"类的字符串传递给此算法?

Thank you all. 谢谢你们。

Solution with gcc-4.6: 使用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 http://liveworkspace.org/code/DPObf

I`m happy! 我很高兴!

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. 我怀疑你最好的办法是创建一个单独的预编译步骤(比如用perl或者这样)来从一组源语句生成hash_cstring语句。 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. 然后,至少您不必在添加新字符串时手动拆分字符串,并且生成完全自动化且可重复。

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: 如果有人感兴趣,我将介绍如何使用C ++ 11 constexpr函数和可变参数模板在这里创建Murmur3_32的编译时哈希:

http://roartindon.blogspot.sg/2014/10/compile-time-murmur-hash-in-c.html 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. Murmur3_32哈希更有趣一点,它一次消耗4个字符,需要一些特殊的大小写代码来处理剩余的0,1,2或3个字节。

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). (给定模板hash_cstring<>能够处理指针值)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM