Шаг 103.
Библиотека STL.
Итераторные адаптеры. Итераторы вставки

    На этом шаге мы рассмотрим разновидности итераторов вставки.

    Итераторы являются чистыми абстракциями; иначе говоря, любой объект, который ведет себя как итератор, является итератором. По этой причине вы можете написать класс, который обладает интерфейсом итератора, но делает нечто совершенно иное. Стандартная библиотека C++ содержит несколько готовых специализированных итераторов, называемых итераторными адаптерами. Не стоит полагать, что итераторные адаптеры являются обычными вспомогательными классами; они наделяют саму концепцию итераторов рядом новых возможностей.

    Далее представлены три разновидности итераторных адаптеров:

Итераторы вставки

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

    Поведение итераторов вставки слегка переопределено.

    Рассмотрим следующий пример:

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

#include <vcl.h>
#include <iostream>
#include <vector>
#include <list>
#include <deque> 
#include <set> 
#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[])
{
  list<int> coll1;
  list<int>::iterator pos1;

  // Вставка элементов со значениями от 1 до 9
  for (int i=1; i<=9; ++i) {
    coll1.push_back(i);
  }

  // Вывод элементов списка
  cout << ToRus("Элементы списка: ");
  for (pos1 = coll1.begin(); pos1 != coll1.end(); ++pos1) {
    cout << *pos1 << ' ';
  }
  cout << endl;

  // Копирование элементов из coll1 в coll2 с присоединением
  vector<int> coll2;
  vector<int>::iterator pos2;

  copy (coll1.begin(), coll1.end(), // Источник
    back_inserter(coll2));  // Приемник

  // Вывод элементов вектора
  cout << ToRus("Элементы вектора: ");
  for (pos2 = coll2.begin(); pos2 != coll2.end(); ++pos2) {
    cout << *pos2 << ' ';
  }
  cout << endl;

  // Изменение размера приемного интервала,
  // чтобы он были достаточен для работы алгоритма
  // с перезаписью.
  coll2.resize (coll1.size());

  // Копирование элементов из первой коллекции во вторую
  // - перезапись существующих элементов в приемном интервале
  copy (coll1.begin(),coll1.end(),   // Источник
    coll2.begin()); // Приемник

  // Копирование элементов coll1 в соll3 со вставкой в начало
  // - порядок следования элементов заменяется на противоположный
  deque<int> coll3;
  deque<int>::iterator pos3;
  copy (coll1.begin(),coll1.end(),   // Источник
    front_inserter(coll3)); // Приемник

  // Вывод элементов дека
  cout << ToRus("Элементы дека: ");
  for (pos3 = coll3.begin(); pos3 != coll3.end(); ++pos3) {
    cout << *pos3 << ' ';
  }
  cout << endl;

  // Копирование элементов coll1 в coll4
  // - единственный итератор вставки, работающий
  // с ассоциативными контейнерами
  set<int> coll4;
  set<int>::iterator pos4;
  copy (coll1.begin(), coll1.end(),  // Источник
    inserter(coll4,coll4.begin()));  // Приемник

  // Вывод элементов множества
  cout << ToRus("Элементы множества: ");
  for (pos4 = coll4.begin(); pos4 != coll4.end(); ++pos4) {
    cout << *pos4 << ' ';
  }
  cout << endl;

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

    Результат работы программы выглядит так:


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

    В этом примере встречаются все три разновидности итераторов вставки.

    В таблице 1 перечислены разновидности итераторов вставки.

Таблица 1. Стандартные итераторы вставки
Выражение Разновидность итератора
back_inserter (контейнер) Элементы присоединяются с конца в прежнем порядке с использованием функции push_back()
front_inserter (контейнер) Элементы вставляются в начало в обратном порядке с использованием функции push_front()
inserter (контейнер, позиция) Элементы вставляются в заданной позиции в прежнем порядке с использованием функции insert()

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




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