|
Программирование >> Операторы преобразования типа
и итераторов ввода). Типичным примером чистого итератора вывода служит итератор для записи в стандартный выходной поток данных (например, на экран или на принтер). Если ргспользовать два итератора вывода для записи на экран, то второе слово будет выводиться после первого, а не поверх него. Другой типичный пример итератора вывода - итератор вставки, предназначеиный для занесения новых значений в контейнер. Операция присваивания приводит к тому, что в контейнер вставляется новый элемент. При последующей записи второе значение не стирает первое, а просто вставляется отдельно от него. Итераторы вставки рассматриваются иа с, 275. Прямые итераторы прямые итераторы представляют собой комбинацию итераторов ввода и вывода. Они обладают всеми свойствами итераторов ввода и большинством свойств итераторов вывода. Операции прямых итераторов перечислены в табл. 7.4. Таблица 7.4. Операции прямых итераторов
В отличие от итераторов ввода и вывода прямые итераторы могут ссылаться на один и тот же элемент коллекции и обрабатывать его по несколько раз. Возможна, вас интересует, почему прямой итератор не обладает всеми свойствами итератора вывода. Существует одно важное ограничение, из-за которого код, действительный для итераторов вывода, оказывается недействительным для прямых итераторов. О Итераторы вывода позволяют записывать данные без проверки конца последовательности. Более того, вы даже не можете сравнить итератор вывода с конечным итератором, потому что итераторы вывода не поддерживают операцию сравнения. Следователыто, для итератора вывода pos следующий цикл правилен, а для прямого итератора -- нет: ОК для итераторов вывода ОШИБКА для прямых итераторов winile (true) { *pos = fooO: ++POS: О При работе с прямыми итераторами перед разыменованием (обращением к данным) необходимо заранее убедиться в том, что это возможно. Приведенный выще цикл неправилен для прямых итераторов, поскольку он приводит к попытке обращения по итератору end() в конце коллекции с непредсказуемыми последствиями. Для прямых итераторов цикл необходимо изменить следующим образом: ОК для пряных итераторов ОШИБКА для итераторов вывода while epos != coll .endO) { *pos = fooC): ++P0S: Для итераторов вывода цикл не компилируется, потому что для них не определен оператор !=. Двунаправленные итераторы Двунаправленными итераторами называются прямые итераторы, поддерживающие возможность перебора элементов в обратном направлении. Для этой цели в них определяется дополнительный оператор -- (табл. 7.5). Таблица 7.5. Дополнительные операции для двунаправленных итераторов Выражение Описание iter Смещение назад (возвращает новую позицию) iter-- Смещение назад (возвращает старую позицию) Итераторы произвольного доступа Итераторами произвольного доступа называются двунаправленные итераторы, поддерживающие прямой доступ к элементам. Для этого в них определяются вычисления с итераторами (по аналогии с математическими вычислениями с обычными указателями) - вы можете щсладывать и вычитать смещения, обрабатывать разности и сравнивать итераторы при помощи операторов отношения (таких, как < и >). В табл. 7.6 перечислены дополнительные операции для итераторов произвольного доступа. Итераторы произвольного доступа поддерживаются следующими объектами и Ti-тами: О контейнеры с произвольным доступом (vector, deque); О строки (string, wstring); О обычные массивы (указатели). Таблица 7.6. Дополнительные операции для итераторов произвольного дсоупа Выражение Описание iter[n] Обращение к элементу с индексом п iter+=n Смещение на п элементов вперед (или назад, если п<0) iter-s=n Смещение на п элементов назад (или вперед, если п<0) iter+n Возвращает итератор для п-го элемента вперед от текущей позиции n+iter Возвращает итератор для п-го элемента вперед от текущей позиции iter-n Возвращает итератор для п-го элемента назад от текущей позиции iterl-iter2 Возвращает расстояние между iterl и iter2 iterl<iter2 Проверяет, что iterl меньше iter2 iterl>iter2 Проверяет, что iterl больше iter2 iterl<=iter2 Проверяет, что iterl предшествует или совпадает с iter2 iterl>=jter2 Проверяет, что iterl не предшествует iter2 Представленная ниже программа демонстрирует особые возможности итераторов произвольного доступа. iter/1 tercet.срр #lnclude <vector> #include <iostream> using namespace std: int mainO { vector<int> coll; Вставка элементов от -3 до 9 for (int i=-3; i<=9; ++i) { coll.push bacl< (1); /* Вывод количества элементов как расстояния между * начальным и конечным итераторами * - ВНИМАНИЕ: применение оператора - для итераторов */ cout number/distance: coll .endO-coll .beginO endl: /* Вывод всех элементов * - ВНИМАНИЕ: применение оператора < вместо оператора != */ vector<int>::iterator pos: for (pos-coll .beginO; pos<coll .endO: ++pos) { cout *pos :
|
© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |