Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
STL_2.doc
Скачиваний:
5
Добавлен:
01.05.2025
Размер:
512.51 Кб
Скачать

3.3. Совместимость алгоритмов и контейнеров

Теперь перейдем к одному из наиболее важных моментов в понимании STL. Хотя некоторые алгоритмы STL, наподобие find и merge, полностью обобщенные, — т.е. они работают с контейнерами любого типа — невозможно соединить любой контейнер с любым алгоритмом библиотеки.

Теоретически все алгоритмы и контейнеры STL можно было бы сделать совместимыми, но это было бы не так просто, поскольку некоторые алгоритмы не могут достаточно эффективно работать с теми или иными контейнерами.

Хорошим примером является алгоритм sort. Используемый алгоритм (вариация алгоритма быстрой сортировки) эффективен только тогда, когда возможен произвольный доступ к данным. Такой произвольный доступ обеспечивают массивы, векторы и деки, но не списки или иные контейнеры STL. Поэтому невозможно написать следующий код:

list<int> list1;

// ... Код вставки значений в list1

sort(list1.begin(), list1.end()); // Неверно!

Класс list предоставляет функцию-член sort, которая эффективно сортирует списки. Например, в приведенном коде эффективно отсортировать list1 можно при помощи вызова listl.sort().

Сейчас вы можете начать подозревать, что STL может не так уж сильно отличаться от традиционных библиотек классов — быть может, у нее тоже используются разные алгоритмы для разных классов. Но по ряду причин это не так. Во-первых, многие алгоритмы STL (наподобие find и merge) совершенно обобщенные. В STL имеется только несколько алгоритмов (наподобие функции-члена sort класса list), специфичных для определенного класса контейнера. Многие алгоритмы, подобно обобщенному алгоритму sort, работают с контейнерами некоторых видов, хотя и не со всеми.

Во-вторых, для тех алгоритмов, которые работают только с итераторами контейнеров определенных видов, нетрудно указать, с какими именно контейнерами они могут использоваться. Нам надо только разобраться, как алгоритмы и контейнеры комбинируются друг с другом с применением итераторов — именно это и будет темой очередной главы.

Глава 4 Итераторы

Итераторы представляют собой указателеобразные объекты, которые алгоритмы STL используют для обхода последовательности объектов, хранящихся в контейнере. Итераторы занимают центральное место в дизайне STL благодаря их роли посредников между контейнерами и обобщенными алгоритмами. Они позволяют создавать обобщенные алгоритмы без учета того, как именно хранятся последовательности данных, а контейнеры — без необходимости написания большого количества исходного текста работающих с ними алгоритмов. Однако, как говорилось в предыдущей главе, по причинам эффективности невозможно обеспечить возможность работы каждого обобщенного алгоритма с каждым контейнером. Но как тогда узнать, какие комбинации возможны? Для ответа на этот вопрос мы должны изучить одну из ключевых технических идей, лежащую в основе STL — разделение итераторов на пять категорий: входные, выходные, однонаправленные, двунаправленные и произвольного доступа (см. рис. 2.1). Мы

начнем эту главу с точного определения этих категорий, а затем покажем, как они используются для определения того, какие алгоритмы могут использоваться теми или иными контейнерами.

Перед тем как мы перейдем к категориям, следует упомянуть еще одну важную концепцию, связанную с тем, как алгоритмы STL используют итераторы, — а именно диапазоны итераторов. Все алгоритмы STL получают доступ к последовательностям через итераторы, обычно посредством пары итераторов first и last, которые указывают начало и конец последовательности. Для того чтобы разобраться, как такая пара итераторов определяет последовательность, используется концепция диапазона итераторов. Диапазон от first до last состоит из итераторов, которые получаются, начиная с итератора first, путем применения оператора operator++ до тех пор, пока не будет достигнут итератор last, но не включая его. Этот диапазон записывается в виде

[first; last)

и называется корректным тогда и только тогда, когда итератор last достижим из итератора first. Все алгоритмы STL полагают, что все диапазоны, с которыми они работают, корректны; результат применения алгоритма к некорректному диапазону не определен.

Важным частным случаем является пустой диапазон, когда first == last. Пустой диапазон корректен, но не содержит итераторов, указывающих на корректные данные.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]