Используйте встроенную специализацию C std::hash для простого целочисленного массива

#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) часто компиляции в идентичный или почти идентичный машинный код.