2016-09-23 5 views
0

Я использую typeid(ClassName).name(), чтобы получить имя для широкого диапазона типов классов. Тем не менее, мне нужно сделать его фиксированным (например, 8 символов). Во многих случаях класс находится в пространстве имен, что делает строку такой длинной, и она не работает, если я просто получаю первые 10 символов.Как получить строку имени класса размера исправления

Кто-нибудь знает хороший способ кодирования/декодирования строки в строку фиксированного размера? Я не могу хранить таблицу для сопоставления hash_code с именем, так как я собираюсь отправить строку на другую машину, у которой нет доступа к карте.

template <typename ClassType> char* get_name(){ 
     return typeid(ClassType).name(); // ?? 
} 
+0

Похоже, вам нужно найти алгоритм сжатия. Не знаю, возможно ли это. – alain

+2

Это очень похоже на [проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – molbdnilo

+0

@molbdnilo, если вы знаете какой-либо другой подход, кроме использования typeid, я буду рад узнать. –

ответ

0

В общем случае невозможно построить функцию преобразования строк произвольной длины в фиксированный домен. Это нарушает pigeonhole principle.

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

Предположит, вы строите класс, через который, чтобы запустить все ваши имена, как это

class compressor { 
    explicit compressor(std::size_t seed); 
    std::string operator()(const std::string &name) const; 
} 

У этого есть два члена: ctor, берущий семя, и operator(), берущую строку имени и возвращающую строку с 8 символами. В вашем коде инициализируйте этот объект некоторым фиксированным, произвольным семенем.

Внутренний объект класса должен содержать отображение unordered_map для каждого отдельного имени, на которое оно было применено, ключ, на который он был нанесен. Первоначально, очевидно, этот внутренний unordered_map будет пустым.

Объект класса должен использовать universal hash function, псевдослучайно выбранный seed в конструкторе. См. Ответ на вопрос this question одним способом создания универсальной хэш-функции.

Когда оператор вызывается, он должен проверить, находится ли это имя во внутреннем unordered_map. Если это так, верните найденный ключ. В противном случае сначала используйте хеш-функцию для вычисления ключа и поместите его во внутренний unordered_map. Однако при создании нового ключа проверьте, сталкивается ли он с существующим ключом, и генерирует исключение, если это так.

Реалистично говоря, поскольку каждое отдельное имя соответствует месту в коде, где вы называете typeid, число различных имен, скажем, п должен быть в 1000s, в лучшем случае. Установить м быть возможно с 8 символами (2).

Вероятность столкновения ~ п/(2 м), которая должна быть незначительной. Таким образом, большинство шансов состоит в том, что не будет никаких столкновений, и никаких исключений не будет. Если кто-то бросил, измените семя и снова запустите программу. Ожидаемое количество раз вам придется сделать это (по истечении начального времени) близко к 0.

Смежные вопросы