Почему не std :: hash & lt; T & gt; специализируется на char *?

Почему в стандарте C ++ не указано, что std::hash<T> специализируется на char*, const char*, unsigned char*, const unsigned char*, так далее? То есть, он хэширует содержимое строки C, пока не будет найден завершающий ноль.

Любой вред при введении моей собственной специализации в std пространство имен для моего собственного кода?

10

Решение

Почему в стандарте C ++ не указано, что std::hash<T> специализируется на char*, const char*, unsigned char*, const unsigned char*, так далее?

Похоже, это произошло из предложение N1456. (акцент мой)

Некоторые более ранние реализации хеш-таблиц обеспечивали специальную обработку char *: она специализировала хеш-функцию по умолчанию для просмотра массива символов, на который указывает указатель, а не сам указатель. Это предложение устраняет этот особый режим. Особый подход облегчает использование хеш-таблиц для строки C, но при стоимость устранения единообразия и усложнения написания универсального кода. Поскольку наивные пользователи, как правило, должны использовать std :: basic_string вместо строк C, стоимость специальной обработки перевешивает выгоду.

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

Какой-нибудь вред от внедрения моих собственных специализаций в пространство имен std для моего собственного кода?

Да, есть потенциальный вред.

  • В будущем все, что вы добавили в std Пространство имен может столкнуться с новым именем символа.
  • В настоящее время все, что вы добавляете в std Пространство имен может быть «лучшим соответствием» для других компонентов стандартной библиотеки, молча нарушая поведение.
13

Другие решения

char * (и тому подобное) не всегда означает строку. Они могут быть простыми байтовыми массивами или дампами двоичных файлов или любым другим. Если вы имеете в виду строку в C ++, вы обычно используете класс «string».

Что касается создания собственного, учитывая вышесказанное, это плохая идея. Однако для пользовательских типов допустимо создавать специализации std :: functions в пространстве имен std ::.

6

Существует стандартная специализация для типов указателей, посмотреть здесь

template< class T > struct hash<T*>;

Таким образом, это может покрыть char* (как последовательность байтов, а не строка в стиле C) тоже.

Если вы имеете в виду специализацию для строк в стиле C, технически это не проблема. Но так как есть специализация для std::string в C ++ не стоит иметь специализацию для строк в стиле C.

Для второй части вашего вопроса, вы можете ввести все в std пространство имен, но что вы получаете? Это против цели пространств имен. Имейте свою собственную территорию пространства имен.

2
По вопросам рекламы [email protected]