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