Таблица 11.8. Функции управления неупорядоченным контейнером
| Взаимодействие с ячейками | |
|---|---|
с.bucket_count() | Количество используемых ячеек |
c.max_bucket_count() | Наибольшее количество ячеек, которое может содержать данный контейнер |
c.bucket_size(n) | Количество элементов в ячейке n |
c.bucket(k) | Ячейка, в которой следует искать элементы с ключом k |
| Перебор ячеек | |
local_iterator | Тип итератора, способный обращаться к элементам в ячейке |
const_local_iterator | Константная версия итератора ячейки |
c.begin(n), c.end(n) | Итераторы на первый и следующий после последнего элементы ячейки n |
c.cbegin(n), c.cend(n) | Возвращают итератор const_local_iterator |
| Политика хеша | |
c.load_factor() | Среднее количество элементов на ячейку. Возвращает тип float |
c.max_load_factor() | Средний размер ячейки, который пытается поддерживать контейнер c. Контейнер с добавляет ячейки, чтобы сохранить соотношение load_factor <= max_load_factor. Возвращает тип float |
c.rehash(n) | Реорганизует хранилище так, чтобы bucket_count >= n и bucket_count > size/max_load_factor |
c.reserve(n) | Реорганизует контейнер c так, чтобы он мог содержать n элементов без вызова функции rehash() |
По умолчанию для сравнения элементов неупорядоченные контейнеры используют оператор == типа ключа. Они также используют объект типа hash при создании хеш-кода для каждого элемента. Библиотека поставляет также версии шаблона hash для некоторых из библиотечных типов, включая строки и интеллектуальные указатели, которые рассматривались в главе 12. Таким образом, можно непосредственно создать неупорядоченный контейнер, ключ которого имеет один из встроенных типов (включающий типы указателей) либо тип string или интеллектуального указателя.
Однако нельзя непосредственно определить неупорядоченный контейнер, использующий для ключа собственные типы классов. В отличие от контейнеров, шаблон хеша нельзя использовать непосредственно. Вместо этого придется предоставить собственную версию шаблона hash. Это будет описано в разделе 16.5.
Вместо хеша по умолчанию можно применить стратегию, подобную используемой при переопределении заданного по умолчанию оператора сравнения ключей упорядоченных контейнеров (см. раздел 11.2.2). Чтобы использовать тип Sales_data для ключа, необходимо предоставить функцию для замены оператора == и вычисления хеш-кода. Начнем с определения этих функций:
size_t hasher(const Sales_data &sd) {
return hash
}
bool eqOp(const Sales_data &lhs, const Sales_data &rhs) {
return lhs.isbn() == rhs.isbn();
}
Чтобы создать хеш-код для переменной-члена ISBN, функция hasher() использует объект библиотечного типа hash для типа string. Точно так же функция eqOp() сравнивает два объекта класса Sales_data, сравнивая их ISBN.
Эти функции можно также использовать для определения контейнера unordered_multiset следующим образом:
using SD_multiset = unordered_multiset
decltype(hasher)*, decltype(eqOp)*>;
//
//
SD_multiset bookstore(42, hasher, eqOp);
Чтобы упростить объявление bookstore, определим сначала псевдоним типа (см. раздел 2.5.1) для контейнера unordered_multiset, у хеша и оператора равенства которого есть те же типы, что и у функций hasher() и eqOp(). Используя этот тип, определим bookstore, передав указатели на функции, которые он должен использовать.
Если у класса есть собственный оператор ==, можно переопределить только хеш-функцию: