我试图创建一个编译时间哈希,它接受一个字符串文字并创建一个整数。我正在使用Code :: Blocks的GCC 4.7.1编译器(之前打破了我)。这是它的工作原理:
typedef unsigned long long ull; //less typing
constexpr ull basis = 14695981039346656037ULL; //Don't ask me
constexpr ull prime = 1099511628211ULL; //Someone else invented them
template <size_t I>
constexpr ull myhash(const char* p, ull b) //Recursive function
{
return myhash<I - 1>(p, (b ^ p[I]) * prime);
}
template <>
constexpr ull myhash<size_t(-1)>(const char* p, ull b) //Base case
{
return b;
}
//This macro generates a variable of a given name with a hash of that name
#define CTH_GEN(x) constexpr ull x = myhash<sizeof("x") - 2>("x", basis)
my_hash
的递归部分将从字符串的末尾开始,并不断地用字符串中的字符更改数字b
,直到它到达基本情况,后者返回数字。宏通过确保变量名和散列始终匹配来减少潜在错误的可能性。 CTH_GEN(A)
评估为constexpr unsigned long long A = my_hash<sizeof("A") - 2>("A", basis)
我测试了这样:
CTH_GEN(A);
CTH_GEN(B);
CTH_GEN(C);
int main()
{
cout << ((basis ^ 'A') * prime) << " : " << A << endl;
cout << ((basis ^ 'B') * prime) << " : " << B << endl;
cout << ((basis ^ 'C') * prime) << " : " << C << endl;
}
这是测试运行的输出:
12638222384927744748 : 12638214688346347271
12638225683462629381 : 12638214688346347271
12638224583951001170 : 12638214688346347271
每侧的数字应该相同。左侧是哈希的运行时计算,右侧是编译时计算。它们都以相同的顺序使用完全相同的数学,但正如您所看到的,编译时版本始终生成相同的数字。我真的很感激解释,解决方法或全新的方法来解决这个问题。我正在使用的特定哈希方法完全可以改变,但我完全认为这是一个不同的问题。
答案 0 :(得分:2)
"x"
不会将宏参数x
转换为字符串;它只代表字符串文字"x"
。
如果要将宏参数转换为字符串,请使用#
运算符即,#x
。