Почему не std:: hash <T> специализирован для char *?

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

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

Ответ 1

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

Похоже, оно было создано из предложения N1456. (акцент мой)

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

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

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

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

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

Ответ 2

char * (и его ilk) не всегда означает строку. Это могут быть простые байт-массивы или двоичные файловые дампы или любое другое. Если вы имеете в виду строку в С++, вы обычно используете класс "string".

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

Ответ 3

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

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

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

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

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