#c #arrays #hash #stl
Вопрос:
У меня есть данные в виде массивов 16-разрядных целых чисел:
uint16_t a[n]
Мне нужна хэш-функция для хранения таких данных в an unordered_set
. Теперь стандартная библиотека предоставляет встроенную специализацию для строк ( string
, u8string
, u16string
, …). То, что я делаю, это:
std::hash<std::u16string>{}(std::u16string((char16_t*)a, n))
Есть ли способ использовать базовую хэш-функцию без затрат на создание и уничтожение строкового объекта и без реализации явного алгоритма хэширования (возможно, хуже, чем стандартный)?
ПРАВКА: Я думал о чем-то вроде общей специализации по хэшу, требующей нескольких итераторов, но, похоже, ее не существует.
Ответ №1:
Это именно то std::basic_string_view
, для чего нужно. Как и следовало ожидать, существуют специализированные типы, одним из которых является std::u16string_view
.
Передайте конструктору указатель и длину. Затем вы можете хэшировать полученный объект.
Комментарии:
1. Разве это не тоже создание объекта? Я понимаю, что это более простой объект, но мне кажется, что базовая форма на основе итератора отсутствует, в отличие от философии STL.
2. Потому что разные типы не должны хэшироваться одинаково. Стандарт не требует использования какого-либо конкретного алгоритма, просто гарантирует, что результаты будут стабильными. Например, числовой тип, соответствующий размеру и знаку результирующего хэш-значения, является операцией идентификации. Он создает объект семантически, но после оптимизации большая часть, если не все, накладных расходов, связанных со строковыми представлениями, оптимизируется, оставляя только хэш-отправку.
3. @m.Алессандрини Построение а
std::string
дорого стоит , потому что оноnew
копирует, аdelete
не потому , что это объект.string_view
представляет собой облегченную оболочку указателя и целого числа. При включенной оптимизации компилятораfoo(std::string_view)
иfoo(const char*, size_t)
часто компиляции в идентичный или почти идентичный машинный код.