Почему 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 пространство имен, но что вы получаете? Это против цели пространств имен. Имейте свою собственную территорию пространства имен.

Другие вопросы по тегам