Итераторы STL. Прямые итераторы

   
На этом шаге мы рассмотрим прямые итераторы.

   
Прямые итераторы представляют собой комбинацию итераторов ввода и вывода. Они обладают всеми свойствами итераторов ввода и
большинством свойств итераторов вывода. Операции прямых итераторов перечислены в таблице 1.

Таблица 1. Операции прямых итераторов

ВыражениеОписание
*iterОбращение к элементу
iter->memberОбращение к переменной или функции элемента
++iterСмещение вперед (возвращает новую позицию)
iter++Смещение вперед (возвращает старую позицию)
iter1 == iter2Проверка двух итераторов на равенство
iter1 != iter2Проверка двух итераторов на неравенство
TYPE()Копирование итератора (конструктор по умолчанию)
TYPE(iter)Копирование итератора (копирующий конструктор)
iter1 = iter2Присваивание итератора

   
В отличие от итераторов ввода и вывода прямые итераторы могут ссылаться на один и тот же элемент коллекции и обрабатывать его по
несколько раз.

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

  • Итераторы вывода позволяют записывать данные без проверки конца последовательности. Более того, вы даже не
    можете сравнить итератор вывода с конечным итератором, потому что итераторы вывода не поддерживают операцию сравнения.
    Следовательно, для итератора вывода pos следующий цикл правилен, а для прямого итератора - нет:

      // ОК для итераторов вывода 
      // ОШИБКА для прямых итераторов 
      while (true) {
        *pos = foo(); 
        ++pos;
      }
    
  • При работе с прямыми итераторами перед разыменованием (обращением к данным) необходимо заранее убедиться в том,
    что это возможно. Приведенный выше цикл неправилен для прямых итераторов, поскольку он приводит к попытке обращения по
    итератору end() в конце коллекции с непредсказуемыми последствиями. Для прямых итераторов цикл необходимо изменить
    следующим образом:

      // ОК для прямых итераторов 
      // ОШИБКА для итераторов вывода 
      while (pos != coll.end()) {
        *pos = foo();
        ++pos: 
      }
    

    Для итераторов вывода цикл не компилируется, потому что для них не определен оператор !=.

   
На следующем шаге мы рассмотрим двунаправленные итераторы.



Вы можете оставить комментарий, или Трекбэк с вашего сайта.

Оставить комментарий