§ 14. Преобразование элементов массива

14.4. Понятие итератора

Итератор — обобщенный указатель [1], который позволяет пользователю перебирать элементы контейнера, без необходимости знать, как реализован сам контейнер.

Вектор является контейнером, в котором реализован последовательный доступ к элементам, итератор позволяет обойти все элементы вектора, перемещение происходит элемент за элементом. Итераторы позволяют обращаться к элементам вектора без использования индексов.

Для вектора определены стандартные итераторы begin() и end(). Итератор begin() указывает на первый элемент в векторе. Итератор end() – на место после последнего элемента вектора.

Для любого итератора (it) доступны следующие операции (пример 14.6):

  • инкремент (it++) — для доступа к следующему элементу;
  • разыменование (*it) — для получения значения элемента;
  • операторы равенства (it1 = = it2) и неравенства (it1 != it2) для определения того, совпадают ли два итератора.

Для вектора итератор обеспечивает дополнительную функциональность:

  • добавление константы (it += 20 сдвинуться на 20 элементов вперед);
  • расстояние между итераторами
    (int dist = it2 - it1).

Начиная со стандарта C++11, обход вектора с помощью итератора может происходить следующим образом:

vector <int> a(n);

for (auto i: a)

  cout << i << " ";

Переменная i, тип которой определяется автоматически, будет поочередно получать значения элементов вектора. Таким образом можно получить значения элементов вектора, но невозможно получить индекс элемента. Такой цикл называют циклом foreach, или циклам, основанным на диапазоне.


[1] Указатель — переменная, обозначающая адрес памяти. Указатель предназначен для прямого обращения по адресу памяти к объекту, который расположен по этому адресу.

Для вектора определены также реверсивные (обратные) итераторы, которые позволяют перебирать элементы контейнера в обратном направлении. Для получения реверсивного итератора применяются функции rbegin() и rend(). Итератор rbegin() указывает на конец текущего вектора, а итератор rend() — на начало вектора.

Пример 14.6. Операции с итератором

vector <int> a = {1, 2, 3, 5, 9};

vector <int> :: iterator it;

Рассмотрим операции:

int x;

it = a.begin();

= *it;

cout << x << endl;

Итератор it указывает на начало вектора. Значение переменной x — значение элемента вектора, на который указывает итератор. Будет выведено значение 1.

it++;

cout << *it << endl;

Итератор сместился на один элемент и теперь указывает на элемент с индексом 1, будет выведено значение 2.

it = a.begin() + 3;

cout << *it << endl;

Итератор сместился на 3 элемента от начала и указывает на элемент с индексом 3, будет выведено значение 5.

if (it == a.begin())

  cout << boolalpha << true;

else

  cout << boolalpha << false;

После предыдущей операции итератор указывает на элемент с индексом 3, поэтому будет выведено false.

int dist1 = it - a.begin();

int dist2 = a.end() - a.begin();

cout <<  dist1 << endl;

cout <<  dist2 << endl;

Будут выведены значения 3 и 5. Значение 5 — количество элементов в векторе.

Циклу foreach соответствует следующая запись цикла for:

vector <int> :: iterator i;

for (= a.begin();

     i != a.end();

     i++)

  cout << *<< " ";

или

  cout << "a % b = " << d << endl;

  cout << "a % b = " << d << endl;

for (auto= a.begin();

  cout << "a % b = " << d << endl;

     i != a.end();

     i++)

  cout << *<< " ";