C++ 编译时字符串哈希

C++ 编译时字符串哈希,c++,boost,metaprogramming,hash,C++,Boost,Metaprogramming,Hash,我需要使用字符串作为ID来获取一些对象。至少,在运行时实现这一点,并且效果良好。但是这使得静态类型检查变得不可能,原因很明显 我在谷歌上搜索了在编译时计算字符串哈希和的算法: 这似乎是我的问题的完美解决方案,除了算法所需的sring应该由4个字符分割成几段,或者一个字符一个字符分割,原因很明显 i、 例如,与通常的当前ID记录不同,我必须这样写: hash_cstring<boost::mpl::string<'obje', 'ct.m', 'etho', 'd'>>::

我需要使用字符串作为ID来获取一些对象。至少,在运行时实现这一点,并且效果良好。但是这使得静态类型检查变得不可能,原因很明显

我在谷歌上搜索了在编译时计算字符串哈希和的算法:

这似乎是我的问题的完美解决方案,除了算法所需的sring应该由4个字符分割成几段,或者一个字符一个字符分割,原因很明显

i、 例如,与通常的当前ID记录不同,我必须这样写:

hash_cstring<boost::mpl::string<'obje', 'ct.m', 'etho', 'd'>>::value
hash_cstring::value
这是绝对不能用的

问题是,如何将字符串(如
“object.method”
)正确传递给此算法


谢谢大家。

我不知道如何使用预处理器或模板来实现这一点。我想最好的办法是创建一个单独的预编译步骤(比如使用perl之类的工具),从一组源语句生成
hash\u cstring
语句。这样,在添加新字符串时,您至少不必手动拆分字符串,而且生成是完全自动且可重复的。

模板可以用任何外部符号实例化,因此这应该可以按预期工作:

external char const* object_method = "object.method";
... = hash_cstring<object_method>::value;
externalcharconst*object\u method=“object.method”;
... = hash_cstring::value;
(给定模板
hash_cstring
能够处理指针值)。

使用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;
}
#包括
模板
结构哈希计算{
静态常量表达式大小\u t应用(常量字符(&s)[N]){
返回(哈希计算::应用^s[I])*16777619u;
};
};
模板
结构哈希计算{
静态常量表达式大小\u t应用(常量字符(&s)[N]){
返回2166136261u;
};
};
模板
常量表达式大小\u t哈希(常量字符(&s)[N]){
返回散列计算::应用;
}
int main(){
字符a[]=“12345678”;

std::cout如果有人感兴趣,我将在这里介绍如何使用C++11 constexpr函数和变量模板创建3_32的编译时哈希:


我看到的大多数示例都处理基于一次使用字符串中的一个字符的哈希。Murruld3_32哈希更有趣,因为它一次使用4个字符,并且需要一些特殊的大小写代码来处理剩余的0、1、2或3个字节。

能否将struct与静态字符串一起使用而不是直接使用字符串ly?也许是一个宏来生成它们?@aaa:宏不拆分标记,它们可以字符串化或连接标记,但不能拆分它们。@Matt macros生成带有名称和静态字符串的结构。例如
#define str(n)struct n{…}
有没有想过使用gperf并将结果包装成一个类型?你真的能用GCC4.6编译它而没有递归错误吗?有趣的是,我的gcc-4.6.1(MingW-TDM)拒绝了带有上述错误的代码(这就是我问这个问题的原因)。在“static constexpr size\u t hash\u calc::apply”(const char(&)[N]的实例化中[无符号整数N=10u,size_t=unsigned int]:从“static constexpr size_t hash_calc::apply(const char(&)[N])递归实例化[无符号整数N=10u,无符号整数I=1u,size_t=unsigned int],“static constexpr size_t hash_calc::apply(const char(&)[N])[unsigned int N=10u,unsigned int I=0u,size\u t=unsigned int]“constexpr size\u t hash(const char(&)[N])实例化而来[unsigned int N=10u,size\u t=unsigned int]”我不确定TDM构建。我使用这些构建: