|
Программирование >> Операторы преобразования типа
Вывод значения элемента cout pos: *pos endl: Преобразование итератора в обратный итератор llst<int>::reverse 1terator rpos(pos); Вывод значения элемента, на который ссылается обратный итератор cout rpos: *rpos endl: Преобразование обратного итератора в обычный llst<int>::iterator rrpos; rrpos = rpos.base(): Вывод значения элемента, на который ссылается итератор cout rrpos: *rrpos endl; Результат выполнения программы выглядит так: pos: 5 rpos: 4 rrpos: 5 Преобразование *rpos.base() эквивалентно преобразованию обратного итератора. Иначе говоря, физическая позиция (элемент, на который ссылается итератор) сохраняется, а логическая позиция (значение элемента) перемещается. Другой пример использования функции base() приведен на с. 350. Итераторы вставки Итератор вставки представляет собой итераторный адаптер, преобразующий присваивание нового значения во вставку нового значения. С помощью итераторов вставки алгоритмы вставляют новые значения вместо того, чтобы записывать их на место старых. Все итераторы вставки относятся к категории итераторов вывода, то есть поддерживают только вставку новых значений (см. с. 259). Функциональность итераторов вставки обычно алгоритмы присваивают значения элементам, на которые ссылаются приемные итераторы. Для примера рассмотрим алгоритм сору() (см. с. 358): namespace std { template <class Inputlterator, class Outputlterator> Outputlterator copy (Inputlterator from pos. Начало источника Inputlterator fron end, Конец источника Outputlterator to pos) Начало приемника while (from pos != from end) { *to pos *from pos: Копирование значений ++from pos; ++t0 p0S; return to pos; Цикл продолжается до тех пор, пока итератор начала источника не дойдет до итератора конца источника. Внутри цикла значение, связанное с итератором from pos, присваивается значению, связанному с итератором приемника to pos, после чего оба итератора увеличиваются. В этом цикле особенно интересна команда присваивания нового значения: *to pos = значение Итератор вставки преобразует эту команду присваивания в команду вставки. Но иа самом деле в этой команде задействованы две операции: сначала оператор * возвращает элемент, на который ссылается итератор, после чего оператор =: присваивает новое значение. В реализации итераторов вставки обычно используется особый фокус , состояп1ий из двух этапов. 1. Оператор * реализуется как фиктивная операция, которая просто возвращает *this. Это означает, что для итераторов вставки выражение *pos эквивалентно pos. 2. Оператор присваивания реализуется так, что преобразуется в команду вставки. В конечном счете оператор вставки вызывает одну из функций контейнера push back(), push front() или insert(). Это означает, что для итераторов вставки включение нового значения может выполняться командой дов=зпачепие вместо *ров=значепие. Впрочем, не стоттг полагаться на подобные особенности реализации итераторов. Правильная команда присваивания должна иметь вид: *ро5=значение Оператор реализуется как фиктивная операция, которая просто возвращает *this. Следовательно, вы не можете изменить позицию итератора вставки. В табл. 7.7 перечислены все операции итераторов вставки. Таблица 7.7. Операции итераторов вставки Выражение Описание *iter Фиктивная операция (возвращает Iter) iterl = value Вставка vaiue ++iter Фиктивная операция (возвращает iter) iter-n- Фиктивная операция (возвращает iter) Разновидности итераторов вставки Стандартная библиотека С++ поддержттвает три разновидности итераторов встав-1ш: конечные, начальные и общие. Они различаются в зависимости от позиции, в которой вставляется новое значение, и вызывают разные функции своего контейнера. Отсюда следует, что итератор вставки всегда должен быть инициализирован своим контейнером. Во всех разновидностях итераторов вставки определены вспомогательные функуцти для создания и инициализации. В табл. 7.8 перечислены разновидности итераторов вставки и их свойства. Таблица 7.8. Разновидности итераторов вставки
Естестве1ню, контейнер должен поддерживать функции, вызываемые итератором вставки; в противном случае использовать соответствующий итератор не удастся. Из-за этого конечные итераторы вставки поддерживаются только для векторов, деков, списков и строк, а начальные итераторы вставки - только для деков и списков. Ниже итераторы вставки рассматриваются более подробно. Конечные итераторы вставки Коиечшяй итератор вставки присоединяет новое значение в конец контейнера вызовом функции push back() (см. с. 247). Функция push back() определена только в векторах, деках, списках и строках, поэтому конечные итераторы вставки поддерживаются только этими контейнерами стандартной библиотеки С++. Конечный итератор вставки должен ннициализироваться контейнером в момент создания. Для этого удобнее всего воспользоваться функцией backjnserter(). Ниже приведен пример применения конечного итератора вставки. 1ter/back1ns.cpp #include <iostreafii> #include <vector> Iinclude <algorlthm> #include print,hpp using namespace std; int mainO vector<int> coll; Создание конечного итератора вставки для coll - неудобный способ back insert iterator<vector<lnt> > iter(coll); Вставка элементов через обычный интерфейс итераторов *iter = 1;
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |