Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Глава 13. Итераторы и функциональные объекты

333

Кроме того, определены три функции вставки:

template <class О back_insert_iterator<C>

back_inserter(C& х); template <class C> front_insert_iterator<C>

front_inserter(C& x): template <class С class Iter> insert_iterator<C>

inserter(C& x, Iter i):

Здесь С — контейнер, в который требуется вЬтавить элементы. Функция backjinserter вставляет элементы в конец контейнера, frontjinserter — в начало, a inserter — перед элементом, на который ссылается ее аргумент-итератор. Эти функции возвращают итераторы соответствующего типа и часто используются в качестве аргументов стандартных алгоритмов (см. 355), где определяют режим работы — вставка или замена элементов контейнера.

Потоковые итераторы

Потоковые итераторы введены для того чтобы стандартные алгоритмы, которые рассматриваются в следующем разделе, могли непосредственно использовать потоки ввода/вывода. Потоки представляются в виде последовательностей. Определено два шаблона классов потоковых итераторов: итератор входного потока istream_iterator и итератор выходного потока ostreamjterator.

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

istream inCtemp"); istream_iterator<int> i(in); int buf = *i;

Очередное значение из входного потока считывается при выполнении операции инкремента, например:

++i;

int bufl = *i:

При достижении конца входного потока итератор принимает значение конца ввода. Это же значение имеет конструктор итератора по умолчанию, поэтому цикл чтения из файла можно организовать следующим образом:

while ( i != istream_iterator<int> () ) cout « *i++ « " ";

Для итераторов входного потока определены операции сравнения на равенство и неравенство. Все итераторы, равные концу ввода, равны между собой. Сравнивать не равные концу ввода итераторы можно при условии, что они сконструированы для одного и того же потока.

Особенность итераторов входного потока заключается в том, что они не сохраняют равенство после инкрементации, то есть если i == j, то не обязательно, что ++i == ++j Поэтому их рекомендуется использовать только в однопроходных ал-

334

Часть III. Стандартная библиотека

горитмах. Если алгоритм требует нескольких проходов, предпочтительнее использовать структуры данных в оперативной памяти.

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

ostream_iterator<int> os(cout, " кг");

*os = 100; // Будет выведено; 100 кг

++os; *os = 2; // Будет выведено; 2 кг

Рассмотрим реализацию операции присваивания:

ostream_iterator& operator=(const Т& value){ *out_stream « value; if(delim != 0) *out_stream « delim; return (*this); } Здесь out_stream — ссылка на выходной поток, заданный первым параметром конструктора итератора, del im — строка, указанная во втором параметре конструктора.

Пример применения потоковых итераторов вместе с алгоритмами библиотеки приведен на с. 350.

Функциональные объекты

Функциональным объектом называется класс, в котором определена операция вызова функции (см. с. 195). Мы уже встречались с функциональными объектами при рассмотрении очередей с приоритетами (с. 313). Чаще всего эти объекты используются в качестве параметров стандартных алгоритмов для задания пользовательских критериев сравнения объектов или способов их обработки.

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

Стандартная библиотека предоставляет множество функциональных объектов, необходимых для ее эффективного использования и расширения. Они описаны в заголовочном файле <functional>. Среди этих объектов можно выделить объекты, возвращающие значения типа bool. Такие объекты называются предикатами. Предикатом называется также и обычная функция, возвращающая bool.

В качестве базовых классов, которые вводят стандартные имена для типов аргументов, в библиотеке определены шаблоны унарной и бинарной функции:

template <class Arg, class Result> struct unary_function{

typedef Arg argument_type;

typedef Result result_type; }: