C++ для начинающих.

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

Вот еще один фрагмент программы, в котором есть тонкая, но серьезная ошибка.

Int ia[] = { 0, 1, 1, 2, 3, 5, 5, 8 };

Vector int ivec( ia, ia+8 ), vres;

// ...

// поведение программы во время выполнения не определено.

Видите ли вы, в чем она заключается?

Unique_copy( ivec.begin(), ivec.end(), vres.begin() );

Проблема вызвана тем, что алгоритм unique_copy() использует присваивание для копирования значения каждого элемента из вектора ivec, но эта операция завершится неудачно, поскольку в vres не выделено место для хранения девяти целых чисел. Можно было бы написать две версии алгоритма unique_copy(): одна присваивает элементы, а вторая вставляет их. Эта последняя версия должна, в таком случае, поддерживать вставку в начало, в конец или в произвольное место контейнера. Альтернативный подход, принятый в стандартной библиотеке, заключается в определении трех адаптеров, которые возвращают специальные итераторы вставки:

* back_inserter() вызывает определенную для контейнера операцию вставки push_back() вместо оператора присваивания. Аргументом back_inserter().

// правильно: теперь unique_copy() вставляет элементы с помощью.

// vres.push_back()...

Unique_copy( ivec.begin(), ivec.end(),

Является сам контейнер. Например, вызов unique_copy() можно исправить, написав:

Back_inserter( vres ) );

* front_inserter() вызывает определенную для контейнера операцию вставки push_front() вместо оператора присваивания. Аргументом front_inserter() тоже является сам контейнер. Заметьте, однако, что класс vector не поддерживает.

// увы, ошибка:

// класс vector не поддерживает операцию push_front().

// следует использовать контейнеры deque или list.

Unique_copy( ivec.begin(), ivec.end(),

Push_front(), так что использовать такой адаптер для вектора нельзя:

Front_inserter( vres ) );

* inserter() вызывает определенную для контейнера операцию вставки insert() вместо оператора присваивания. inserter() принимает два аргумента: сам.

Unique_copy( ivec.begin(), ivec.end(),

Контейнер и итератор, указывающий позицию, с которой должна начаться вставка:

Inserter( vres ), vres.begin() );

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

Vector int ::iterator iter = vres.begin(),

Iter2 = ivec.begin();

For ( ; iter2 != ivec.end() ++ iter, ++iter2 ).

Vres.insert( iter, *iter2 );