Шаг 105.
Библиотека STL.
Итераторные адаптеры. Обратные итераторы

    На этом шаге мы рассмотрим особенности использования обратных итераторов.

    Третей разновидностью итераторных адаптеров STL являются обратные итераторы. Эти итераторы работают в противоположном направлении: вызов оператора ++ на внутреннем уровне преобразуется в вызов оператора --, и наоборот. Все контейнеры поддерживают создание обратных итераторов функциями rbegin() и rend(). Рассмотрим следующий пример:

//---------------------------------------------------------------------------

#include <vcl.h>
#include <iostream>
#include <iterator>
#include <vector>
#include <string>
#include <algorithm>
#include <conio.h> //необходимо для getch()
#pragma hdrstop

//---------------------------------------------------------------------------

#pragma argsused
using namespace std;
std::string ToRus(const std::string &in)
{
  char *buff = new char [in.length()+1];
  CharToOem(in.c_str(),buff);
  std::string out(buff);
  delete [] buff;
  return out;
}

int main(int argc, char* argv[])
{
  vector<int> coll;
  vector<int>::iterator pos;

  // Вставка элементов со значениями от 1 до 9
  for (int i=1; i<=9; ++i) {
    coll.push_back(i);
  }
  cout << ToRus("Элементы вектора:\n");
  for (pos = coll.begin(); pos != coll.end(); ++pos) {
    cout << *pos << ' ';
  }
  cout << endl;

  // Вывод всех элементов в обратном порядке
  cout << ToRus("Элементы вектора в обратном порядке:\n");
  copy (coll.rbegin(), coll.rend(), // Источник
    ostream_iterator<int>(cout," "));   // Приемник cout

  cout << endl;

  getch();
  return 0;
}
//---------------------------------------------------------------------------
Текст этого примера можно взять здесь.

    Выражение coll.rbegin() возвращает обратный итератор для коллекции coll. Полученный итератор может использоваться, чтобы начать обратный перебор элементов коллекции, поскольку он устанавливается на последний элемент коллекции. Таким образом, выражение *coll.rbegin() возвращает значение последнего элемента.

    Соответственно выражение coll.rend() возвращает обратный итератор для коллекции coll, который может использоваться для завершения перебора в обратном направлении. По аналогии с обычными интервалами он устанавливается за концом интервала, но в противоположном направлении - то есть перед первым элементом коллекции.

    Значение выражения *coll.rend() не определено, как, впрочем, и значение *coll.end(). Никогда не используйте операторы * и -> с позициями, не представляющими реальных элементов коллекции.

    Основное достоинство обратных итераторов заключается в том, что все алгоритмы получают возможность работать в обратном направлении без модификации кода. Переход к следующему элементу оператором ++ преобразуется в переход к предыдущему элементу оператором --. В нашем примере алгоритм сору() перебирает все элементы coll от последнего к первому, поэтому результат работы программы выглядит так:


Рис.1. Результат работы приложения

    "Нормальные" итераторы можно переключать в режим обратного перебора и наоборот. Однако следует помнить, что при этом изменяется текущий элемент, связанный с итератором.

    Со следующего шага мы начнем знакомиться с модифицирующими алгоритмами.




Предыдущий шаг Содержание Следующий шаг