- •Итераторы
- •Основные понятия
- •Классификация итераторов
- •Свойства итераторов различных типов
- •Последовательные итераторы
- •Двунаправленные итераторы2
- •Итераторы произвольного доступа3
- •Итераторы ввода
- •Итераторы вывода
- •Использование итераторов
- •Вставка одного или нескольких элементов в позицию, указываемую итератором
- •Адаптеры итераторов и итераторы потоков ввода-вывода
- •Итераторы потоков ввода-вывода
- •Итераторы вставки (insert iterators).
- •Функции advance и distance
- •Теги и свойства итераторов5
- •Как написать свой итератор
Классификация итераторов
В STLСуществует 5 категорий итераторов, в зависимости от определенных для них операций и правил использования:
Итераторы последовательного доступа
Двунаправленные итераторы (bidirectional)
Итераторы произвольного доступа (random access)
Итераторы ввода (input)
Итераторы вывода (output)
Итераторы также могут быть константными (constant,read-only) иизменяемыми(read/writeилиwrite-only): константный итератор допускает лишь чтение, изменяемый допускает запись. Не следует неверно понимать слово «константный» как невозможность изменить сам итератор – оно означает лишь невозможность изменить значение элемента, на который указывает итератор. Кроме того в данном случае константный итератор не является обычным итератором объявленным с модификаторомconst, это другой тип итератора, так стандартные контейнеры (напримерvector) поддерживают два имени типаiteratorдля неконстантных итераторов иconst_iteratorдля константных.
Итератор последовательного доступапозволяет осуществлять перебор элементов коллекции лишь последовательно в одном направлении. Таков, к примеру, итератор потока данных от какого-нибудь устройства.
Двунаправленные итераторыпозволяют просматривать коллекцию в двух направлениях, т.е. для каждого элемента перейти к следующему или предыдущему – например, итератор двухсвязного списка.
Итератор произвольного доступапозволяет обратиться к элементу непосредственно по его номеру. Типичный пример – обычный массив илиvector.
Итератор ввода представляет собой частный случай последовательного константного итератора. Его важным отличием от вышеупомянутых типов является то, что
Если iдостижим изjиi!=j, то действительным в общем случае является толькоi, но неj
Два итератора ввода в общем случае равны (и – более того – одновременно действительны) тогда и только тогда, когда это копии одного и того же итератора
Алгоритмы, использующие итератор ввода, не должны проходить через одно значение итератора дважды, т.е. должны быть однопроходными.
Эти свойства становятся очевидными, если вспомнить, что итератор ввода может быть, к примеру, итератором потока данных: увеличение итератора означает выбор следующего байта из потока и при этом 1) теряется предыдущий байт и 2)Рассмотрим выражение ++i==++j. ++i и ++jбудут в любом случае выполнены последовательно и если первым будет увеличен итераторi, то после этогоjбудет уже недействительным и для него результат операции инкремента будет неопределен.
Итератор вывода– также частный случай последовательного итератора. Помимо свойств, аналогичных вышеописанным свойствам итератора ввода он обладает еще одним: прежде чем увеличивать итератор вывода, необходимо что-нибудь записать в элемент, указываемый им, т.е. последовательность действийj++;j++ недопустима.
Заметим, что эти итераторы укладываются в следующую иерархию:
То есть последовательный итератор удовлетворяет требованиям итератора ввода и вывода, двунаправленный итератор – требованиям последовательного, произвольного доступа – требованиям двунаправленного. Более четкую формализацию свойств различных категорий итераторов см. в части «Свойства различных типов итераторов».
Константные итераторы предоставляют пользователю лишь право чтения указываемых элементов последовательности. Изменяемые либо предоставляют только право записи, либо право и чтения, и записи.
Всякий итератор ввода, к примеру, является константным; итератор массива обычно предоставляет право и чтения, и записи; всякий итератор вывода предоставляет только право записи.