2

我试图创建一个编译时哈希器,它接受一个字符串文字并创建一个整数。我正在使用 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

每边的数字应该相同。左边是哈希的运行时计算,右边是编译时计算。它们都以相同的顺序使用完全相同的数学,但正如您所见,编译时版本总是生成相同的数字。我真的很感激解释,解决方法或全新的方法来解决这个问题。我使用的特定哈希方法完全可以更改,但我认为这完全是一个不同的问题。

4

1 回答 1

2

"x"不会将宏参数x转换为字符串;它只代表字符串文字"x"

如果要将宏参数转换为字符串,请使用#运算符,, #x

于 2014-08-29T03:25:14.390 回答