// класс 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 );
12.4.2. Обратные итераторы
Операции begin() и end() возвращают соответственно итераторы, указывающие на первый элемент и на элемент, расположенный за последним. Можно также вернуть обратный итератор, обходящий контейнер от последнего элемента к первому. Во всех контейнерах для поддержки такой возможности используются операции rbegin() и rend(). Есть константные и неконстантные версии обратных итераторов:
vector int vec0;
const vector int vec1;
vector int ::reverse_iterator r_iter0 = vec0.rbegin();
vector int ::const_reverse_iterator r_iter1 = vec1.rbegin();
Обратный итератор применяется так же, как прямой. Разница состоит в реализации операторов перехода к следующему и предыдущему элементам. Для прямого итератора оператор ++ дает доступ к следующему элементу контейнера, тогда как для обратного – к предыдущему. Например, для обхода вектора в обратном направлении следует написать:
// обратный итератор обходит вектор от конца к началу
vector type ::reverse_iterator r_iter;
for ( r_iter = vec0.rbegin(); // r_iter указывает на последний элемент
r_iter != vec0.rend(); // пока не достигли элемента перед первым
r_iter++ ) // переходим к предыдущему элементу
{ /* ... */ }
Инвертирование семантики операторов инкремента и декремента может внести путаницу, но зато позволяет программисту передавать алгоритму пару обратных итераторов вместо прямых. Так, для сортировки вектора в порядке убывания мы передаем алгоритму
// сортирует вектор в порядке возрастания
sort( vec0.begin(), vec0.end() );
// сортирует вектор в порядке убывания
sort() пару обратных итераторов:
sort( vec0.rbegin(), vec0.rend() );
12.4.3. Потоковые итераторы
Стандартная библиотека предоставляет средства для работы потоковых итераторов чтения и записи совместно со стандартными контейнерами и обобщенными алгоритмами. Класс istream_iterator поддерживает итераторные операции с классом istream или одним из производных от него, например ifstream для работы с потоком ввода из файла. Аналогично ostream_iterator поддерживает итераторные операции с классом ostream или одним из производных от него, например ofstream для работы с потоком вывода в файл. Для использования любого из этих итераторов следует включить заголовочный файл
#include iterator
В следующей программе мы пользуемся потоковым итератором чтения для получения из стандартного ввода последовательности целых чисел в вектор, а затем применяем потоковый итератор записи в качестве целевого в обобщенном алгоритме
#include iostream
#include iterator
#include algorithm
#include vector
#include functional
/*
* вход:
* 23 109 45 89 6 34 12 90 34 23 56 23 8 89 23
*
* выход:
* 109 90 89 56 45 34 23 12 8 6
*/
int main()
{
istream_iterator int input( cin );
istream_iterator int end_of_stream;
vectorint vec;