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

    На этом шаге мы рассмотрим общие итераторы вставки.

    Общий итератор вставки инициализируется двумя значениями: контейнером и позицией вставки элементов. На основании этой информации вызывается функция insert(), которой заданная позиция передается в качестве аргумента.

    Функция inserter() обеспечивает удобный способ создания и инициализации общего итератора вставки.

    Общие итераторы вставки поддерживаются всеми стандартными контейнерами, потому что необходимая функция insert() определена во всех контейнерах. Тем не менее в ассоциативных контейнерах (множествах и отображениях) передаваемая позиция имеет рекомендательный, а не обязательный характер, поскольку правильная позиция элемента определяется его значением. За подробностями обращайтесь к описанию функции insert() на 202 шаг.

    После вставки общий итератор вставки переходит в позицию вставленного элемента. Выполняются следующие команды:

  pos = контейнер.insert(pos,value); 
  ++pos;
Присваивание итератору возвращаемого значения функции insert() гарантирует, что позиция итератора всегда остается действительной. Без присваивания новой позиции в деках, векторах и строках общий итератор вставки сам делал бы себя недействительным, поскольку каждая операция вставки, по крайней мере теоретически, может сделать недействительными все итераторы, ссылающиеся на контейнер.

    Пример использования общего итератора вставки:

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

#include <vcl.h>
#include <iostream>
#include <iterator>
#include <list>
#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;
}

template <class T>
inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="")
{
  typename T::const_iterator pos;
  std::cout << ToRus(optcstr);
  for (pos=coll.begin(); pos!=coll.end(); ++pos) {
    std::cout <<*pos <<' ';
  }
  std::cout << std::endl;
}


int main(int argc, char* argv[])
{
  set<int> coll;

  // Создание общего итератора вставки для coll 
  // - неудобный способ 
  insert_iterator<set<int> > iter(coll,coll.begin());

  // Вставка элементов через обычный интерфейс итераторов
  *iter = 1;
  iter++;
  *iter = 2;
  iter++;
  *iter = 3;

  PRINT_ELEMENTS(coll,"Множество: ");

  // Создание общего итератора вставки и вставка элементов 
  // - удобный способ 
  inserter(coll,coll.end()) = 44; 
  inserter(coll,coll.end()) = 55; 
  PRINT_ELEMENTS(coll,"Множество после добавления: ");

  // Вставка всех элементов контейнера с использованием 
  // общего итератора вставки 
  list<int> coll2;
  copy (coll.begin(), coll.end(),       // Источник
        inserter(coll2,coll2.begin())); // Приемник
  PRINT_ELEMENTS(coll2,"Список: ");

  // Вставка всех элементов контейнера перед вторым элементом
  // с использованием общего итератора вставки
  copy (coll.begin(), coll.end(),          // Источник
        inserter(coll2,++coll2.begin()));  // Приемник
  PRINT_ELEMENTS(coll2,"Список после добавления: ");

  getch();
  return 0;
}

//---------------------------------------------------------------------------
Текст этого примера можно взять здесь.

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


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

    Вызовы сору() доказывают, что общий итератор вставки сохраняет порядок следования элементов. При втором вызове сору() в качестве аргумента передается позиция внутри интервала.

    На следующем шаге мы рассмотрим пользовательские итераторы вставки для ассоциативных контейнеров.




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