Язык программирования C++. Вводный курс


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


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

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()

можно исправить, написав:

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

// vres.push_back()...

unique_copy( ivec.begin(), ivec.end(),

             back_inserter( vres ) );

·         front_inserter()

вызывает определенную для контейнера операцию вставки push_front()

вместо оператора присваивания. Аргументом front_inserter()

тоже является сам контейнер. Заметьте, однако, что класс vector не поддерживает push_front(), так что использовать такой адаптер для вектора нельзя:

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

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

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

unique_copy( ivec.begin(), ivec.end(),

             front_inserter( vres ) );

·         inserter()




Начало  Назад  Вперед