Предоставляет ли C++11 функции хеширования для std::type_info?
-
30-09-2019 - |
Вопрос
Я все еще работаю над хорошим решением моей Проблема с единственным в своем роде контейнером -- и, поразмыслив, я думаю, что было бы неплохо иметь возможность просто использовать что-то вроде std::map<std::type_info, boost::any>
.К сожалению, std::type_info
не определяет operator<
, и я думаю, что было бы неразумно давать такое определение.
Однако кажется разумным определить для него хэш-функцию, потому что вы можете просто использовать одноэлементный адрес std::type_info
объект как разумный «хэш».Таким образом, вы можете поставить std::type_info
в std::unordered_map
как ключ.
Предоставляет ли C++11 такую хэш-функцию?Будет ли использование адреса памяти std::type_info
Singleton — плохая стратегия хеширования?
Решение
Дело в том, что type_info
не менее чем сопоставим, не такая уж проблема для его использования в качестве ключа карты, как тот факт, что type_info
не подлежит копированию.:-)
В С++03 type_info
имеет before()
функция-член, которая обеспечивает упорядочивание type_info
объекты.
В С++11 type_info
имеет hash_code()
функция-член (C++11 §18.7.1/7):
size_t hash_code() const throw();
Возврат: неопределенное значение, за исключением того, что в течение одного выполнения программы она должна возвращать одно и то же значение для любых двух
type_info
объекты, которые сравниваются равными.Примечание: реализация должна возвращать разные значения для двух
type_info
объекты, которые не сравниваются равными.
type_info
объекты, возникшие в результате typeid
существует до конца программы, поэтому можно безопасно использовать type_info*
в качестве ключа карты.Однако, насколько мне известно, нет никакой гарантии, что если вы подадите заявку typeid
к двум объектам одного и того же типа вы получите две ссылки на один и тот же тип. type_info
объект.
Если вы используете type_info*
в качестве ключа карты я бы использовал собственный компаратор, который разыменовывает указатели и сравнивает type_info
сами объекты (используя вышеупомянутое before()
или hash_code()
для заказа).
Другие советы
Вы также можете использовать type_index, он надежно хранит указатель на type_info, его можно копировать, сравнивать, а для стандартных контейнеров предусмотрена хэш-функция.