хеширование строк во время компиляции - PullRequest
12 голосов
/ 12 февраля 2011

Мне нужно использовать строку в качестве идентификатора для получения какого-либо объекта. При реализации это во время выполнения, и работает хорошо. Но это делает статическую проверку типов невозможной по понятным причинам.

Я погуглил алгоритм вычисления хэш-суммы строки во время компиляции: C ++ хеширование строки времени компиляции с Boost.MPL .

Кажется, это идеальное решение моей проблемы, за исключением того, что sring, необходимый для алгоритма, должен быть разбит на куски по 4 символа, или по символам, по понятным причинам.

т.е. вместо обычной текущей записи идентификаторов, мне придется написать так:

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

Это абсолютно непригодно для использования.

Вопрос в том, как правильно передать строку, такую ​​как "object.method", в этот алгоритм?

Спасибо всем.

Ответы [ 4 ]

8 голосов
/ 16 февраля 2011

раствор с 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

Я счастлив!

5 голосов
/ 12 февраля 2011

Я не знаю, как это сделать с помощью препроцессора или с помощью шаблонов. Я подозреваю, что вам лучше всего создать отдельный шаг перед компиляцией (скажем, с помощью perl или чего-то подобного) для генерации операторов hash_cstring из набора исходных операторов. Тогда, по крайней мере, вам не придется разбивать строки вручную при добавлении новых, и генерация полностью автоматизирована и повторяется.

1 голос
/ 29 октября 2014

На случай, если кому-то будет интересно, я расскажу, как создать хэш времени компиляции Murmur3_32 с использованием функций constexpr C ++ 11 и шаблонов переменных здесь:

http://roartindon.blogspot.sg/2014/10/compile-time-murmur-hash-in-c.html

Большинствопримеры, которые я видел, касаются хэшей, основанных на использовании одного символа строки за раз.Хэш Murmur3_32 немного более интересен тем, что он использует 4 символа за раз и нуждается в специальном коде для обработки оставшихся 0, 1, 2 или 3 байтов.

1 голос
/ 12 февраля 2011

Шаблоны могут быть созданы с любым внешним символом, поэтому это должно работать должным образом:

external char const* object_method = "object.method";
... = hash_cstring<object_method>::value;

(учитывая, что шаблон hash_cstring<> может работать со значениями указателя).

...