Вход/Регистрация
Эффективное использование STL
вернуться

Мейерс Скотт

Шрифт:

Из всех существующих реализаций хэшированных контейнеров наибольшее распространение получили две: от SGI (совет 50) и от Dinkumware (приложение Б), поэтому дальнейшее описание ограничивается устройством хешированных контейнеров от этих разработчиков. STLport (совет 50) также содержит хэшированные контейнеры, но они базируются на реализации SGI. В контексте настоящего примера все сказанное о хэшированных контейнерах SGI относится и к хэшированным контейнерам STLport.

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

template<typename T, typename HashFunction, typename CompareFunction,

 typename Allocator = allocator<T> >

class hash_контейнер;

Полученное объявление весьма близко к объявлению хэшированных контейнеров в реализации SGI. Главное различие между ними заключается в том, что в реализации SGI для типов

HashFunction
и
CompareFunction
предусмотрены значения по умолчанию. Объявление
hash_set
в реализации SGI выглядит следующим образом (слегка исправлено для удобства чтения):

template<typename T,

 typename HashFunction = hash<T>,

 typename CompareFunction = equal_to<T>,

 typename Allocator = allocator<T> >

class hash_set;

В реализации SGI следует обратить внимание на использование

equal_to
в качестве функции сравнения по умолчанию. В этом она отличается от стандартных ассоциативных контейнеров, где по умолчанию используется функция сравнения
less
. Смысл этого изменения не сводится к простой замене функции. Хэшированные контейнеры SGI сравнивают два объекта, проверяя их равенство, а неэквивалентность (см. совет 19), Для хэшированных контейнеров такое решение вполне разумно, поскольку в хэшированных ассоциативных контейнерах, в отличие от их стандартных аналогов (обычно построенных на базе деревьев), элементы не хранятся в отсортированном порядке.

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

hash_compare
, который передается по умолчанию в параметре
HashingInfo
шаблона контейнера.

Например, объявление

hash_set
(также отформатированное для наглядности) в реализации Dinkumware выглядит следующим образом:

template<typename T, typename CompareFunction>

class hash_compare;

template<typename T,

 typename Hashinglnfo = hash_compare<T, less<T>>,

 typename Allocator = allocator<T>>

class hash_set;

В этом интерфейсе внимание стоит обратить на использование параметра

HashingInfo
, содержащего функции хэширования и сравнения, а также перечисляемые типы, управляющие минимальным количеством гнезд в таблице и максимальным допустимым отношением числа элементов контейнера к числу гнезд. В случае превышения пороговой величины количество гнезд в таблице увеличивается, а некоторые элементы в таблице хэшируются заново (в реализации SGI предусмотрены функции, обеспечивающие аналогичные возможности управления количеством гнезд в таблице).

После небольшого форматирования объявление

hash_compare
(значение по умолчанию для
HashingInfo
) выглядит примерно так:

template<typename T ,typename CompareFunction=less<T> >

class hash_compare {

public:

 enum {

bucket_size = 4, // Максимальное отношение числа элементов к числу гнезд

min_buckets = 8 // Минимальное количество гнезд

 }

 size_t operator(const T&) const; // Хэш-функция

 bool operator (const T&, const T&) const;

 … // Некоторые подробности опущены,

// включая использование CompareFunction

};

Перегрузка

operator
(в данном случае для реализации функций хэширования и сравнения) используется гораздо чаще, чем можно представить. Другое применение этой концепции продемонстрировано в совете 23.

Реализация Dinkumware позволяет программисту написать собственный касс-аналог

hash_compare
(возможно, объявленный производным от
hash_compare
). Если этот класс будет определять
bucket_size
,
min_buckets
, две функции
operator
(с одним и с двумя аргументами) и еще несколько мелочей, не упомянутых выше, он может использоваться для управления конфигурацией и поведением контейнеров Dinkumware
hash_set
и
hash_multiset
. Управление конфигурацией
hash_map
и
hash_multimap
осуществляется аналогичным образом.

  • Читать дальше
  • 1
  • ...
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: