Что я должен передать аргументу счетчика сегментов unordered_map, если я просто хочу указать хеш-функцию?

Конструктор по умолчанию unordered_map в С++ 11 выглядит следующим образом:

explicit unordered_map( size_type bucket_count = /*implementation-defined*/,
                    const hasher& hash = hasher(),
                    const key_equal& equal = key_equal(),
                    const allocator_type& alloc = allocator_type() );

Я хочу создать unordered_map с пользовательской хеш-функцией, но это второй аргумент конструктора.

Какое количество ведер следует использовать? Есть ли волшебное значение, которое я могу использовать, чтобы сообщить контейнеру, что он должен решать сам? В противном случае, есть ли эвристика, которую я могу использовать, чтобы угадать хороший номер корзины на основе чего-то вроде количества ключей, которые, как я ожидаю, будет содержать моя карта? Должен ли я даже заботиться?


person zneak    schedule 06.01.2013    source источник


Ответы (2)


Я бы не стал слишком беспокоиться об этом.

Контейнер гарантирует, что счетчик сегментов будет минимум от указанного вами значения, т. е. он увеличит его при необходимости. Вы можете передать ноль в качестве счетчика сегментов, и реализация либо сделает что-то вроде std::max(count, 10) и переопределит нулевое значение, либо просто перефразирует при первой вставке.

Другой альтернативой может быть копирование значения из объекта, созданного по умолчанию:

H hasher;
unordered_map<K,T,H,P> m{ unordered_map<K,T,H,P>{}.bucket_count(), hasher };

Это установит счетчик бакетов на значение по умолчанию для реализации (но требует, чтобы тип хеш-функции H был DefaultConstructible.)

FWIW GCC unordered_map использует 10 по умолчанию для показанного вами конструктора (так что это, вероятно, тоже разумное значение по умолчанию) и использует 0 для конструкторов, принимающих пару итераторов или initializer_list.

person Jonathan Wakely    schedule 06.01.2013
comment
Хороший трюк. Не думал об этом. Спасибо за внимание. - person zneak; 06.01.2013
comment
Вы уверены насчет std::min? Если вам нужно не менее 10 элементов, используйте формулу std::max(count, 10). - person fredoverflow; 06.01.2013

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

person mike__t    schedule 06.01.2013
comment
Хотя я согласен с вами, вы можете указать тип хэшера в качестве аргумента шаблона, но все же вам нужно предоставить конкретный объект хэша для unordered_map при построении, если вы хотите сделать что-то необычное (например, , если ваш хэшер был универсальным семейством хэш-функций и вам нужно было указать, какую из этих хеш-функций использовать). - person templatetypedef; 06.01.2013
comment
Rapptz предложил это в чате C++. Это действительно работает для моих целей, так как я просто собирался передать указатель на функцию (поэтому обертывание его в структуру не имеет большого значения), и это определенно стоит упомянуть, но, как говорит @templatetypedef, это не так. на самом деле помочь людям, которые действительно должны дать счет ведро. - person zneak; 06.01.2013