hash — генератор уникальных идентификаторов времени компиляции C ++ всегда возвращает одно и то же значение

Я пытался создать хэш времени компиляции, который принимает строковый литерал и создает целое число. Я использую компилятор 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

Номера должны быть одинаковыми на каждой стороне. Левая сторона — это вычисление времени выполнения хэша, а правая сторона — это вычисление времени компиляции. Они оба используют одну и ту же математику в одном и том же порядке, но, как вы можете видеть, версия времени компиляции всегда генерирует одно и то же число. Я был бы очень признателен за объяснение, обходной путь или совершенно новый подход к этому. Конкретный метод хеширования, который я использую, полностью открыт для изменений, но я полагаю, что это совершенно другой вопрос.

2

Решение

"x" не включает параметр макроса x в строку; это просто означает строковый литерал "x",

Если вы хотите превратить параметр макроса в строку, используйте # оператор, то есть, #x,

2

Другие решения


По вопросам рекламы [email protected]