Почему std::hash<T> не специализирован для char*?
Почему в стандарте C++ не указано, что std::hash<T>
специализируется на char*
, const char*
, unsigned char*
, const unsigned char*
, так далее? То есть, он хэширует содержимое строки C, пока не будет найден завершающий ноль.
Любой вред при введении моей собственной специализации в std
пространство имен для моего собственного кода?
3 ответа
Почему в стандарте C++ не указано, что
std::hash<T>
специализируется наchar*
,const char*
,unsigned char*
,const unsigned char*
, так далее?
Похоже, он возник из предложения N1456. (акцент мой)
В некоторых ранних реализациях хеш-таблиц была предусмотрена специальная обработка char*: она специализировала хеш-функцию по умолчанию для просмотра указываемого массива символов, а не сам указатель. Это предложение устраняет этот особый режим. Специальный подход облегчает использование хеш-таблиц для строки C, но за счет устранения единообразия и усложнения написания универсального кода. Поскольку обычно наивные пользователи, как ожидается, будут использовать std::basic_string вместо строк C, стоимость специальной обработки перевешивает выгоду.
Если я правильно интерпретирую это, то причина состоит в том, что поддержка строк в стиле C нарушит код, который в общем случае действует на хеши указателей.
Какой-нибудь вред от внедрения моих собственных специализаций в пространство имен std для моего собственного кода?
Да, есть потенциальный вред.
- В будущем все, что вы добавили в
std
Пространство имен может столкнуться с новым именем символа. - В настоящее время все, что вы добавляете в
std
Пространство имен могло бы быть "лучшим соответствием" для других компонентов стандартной библиотеки, молча нарушая поведение.
char* (и тому подобное) не всегда означает строку. Они могут быть простыми байтовыми массивами или дампами двоичных файлов или любым другим. Если вы имеете в виду строку в C++, вы обычно используете класс "string".
Что касается создания собственного, учитывая вышесказанное, это плохая идея. Однако для пользовательских типов допустимо создавать специализации std:: functions в пространстве имен std::.
Существует стандартная специализация для типов указателей, см. Здесь
template< class T > struct hash<T*>;
Таким образом, это может покрыть char*
(как последовательность байтов, а не строка в стиле C) тоже.
Если вы имеете в виду специализацию для строк в стиле C, технически это не проблема. Но так как есть специализация для std::string
в C++ не стоит иметь специализацию для строк в стиле C.
Для второй части вашего вопроса, вы можете ввести все в std
пространство имен, но что вы получаете? Это против цели пространств имен. Имейте свою собственную территорию пространства имен.