Скачиваний:
189
Добавлен:
05.07.2021
Размер:
16.53 Mб
Скачать

18. Использование алгоритма copy(), классов ostream_iterator и istream_iterator в качестве моделей входных и входных итераторов

Предположим, что требуется отобразить содержимое контейнера dice. Можно воспользоваться методом сору() и ostream_iterator для копирования содержимого в выходной поток:

ostream_iterator<int,char> out_iter(cout, " ");

copy(dice.begin(), dice.end(), out_iter);

для отображения содержимого в обратном порядке можно применить следующий оператор:

copy(dice.rbegin(), dice.rend(), out_iter);

Обратный итератор даже не нужно объявлять.

19. Итераторы специального назначения: reverse_iterator, back_insert_iterator, front_insert_iterator, insert_iterator

Итератор back_insert_iterator вставляет элементы в конец контейнера, а front_insert_iterator — в его начало, а insert_iterator вставляет элементы перед позицией, указанной в аргументе конструктора insert_iterator. Все эти три итератора являются моделями концепции выходного контейнера.

Однако существуют некоторые ограничения. Так, например, back_insert_iterator может применяться только с контейнерными типами, которые допускают быструю вставку в конец. Термин быстрая относится к алгоритму с постоянным временем. Класс vector позволяет это делать.

Итератор front_insert_iterator может использоваться только с контейнерными типами, допускающими вставку в начало за постоянное время. Класс vector не позволяет это делать, а класс queue — позволяет. Итератор insert_iterator не обладает этими ограничениями, т.е. его можно применять для вставки данных в начало вектора. Однако front_insert_iterator выполняет это быстрее с теми контейнерными типами, которые поддерживают его применение.

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

Эти итераторы принимают тип контейнера в качестве аргумента шаблона и фактический идентификатор контейнера — как аргумент конструктора. Таким образом, чтобы создать итератор back_insert_iterator для контейнера vector<int> по имени dice, нужно написать следующий оператор:

vector<int> dice(10);

back_insert_iterator<vector<int>> back_iter(dice);

Необходимость объявления типа контейнера обусловлена тем, что итератор должен применять соответствующий метод контейнера.

20. Шаблон initializer_list (C++11). Его использование.

Шаблон initializer_list является еще одним дополнением С++11 к библиотеке C++. Синтаксис списка инициализаторов можно использовать для инициализации контейнера STL списком значений:

vector<double> payments {45.99, 39.23, 19.95, 89.01};

Подобное возможно благодаря тому, что теперь классы контейнеров имеют конструкторы, которые принимают аргумент initializer_list<Type>. Например, объект vector<double> имеет конструктор, который принимает аргумент initializer_list<double>, и предыдущее объявление эквивалентно следующему:

vector<double> payments ({45.99, 39.23, 19.95, 89.01});

В этом примере список явно записан в виде аргумента конструктора.

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

Объекты initializer_list можно применять в коде, подключая заголовочный файл initializer_list. Класс шаблона имеет элементы begin() и end(), и их можно использовать для получения доступа к элементам списка. Класс имеет также элемент size(), который возвращает количество элементов.

initializer_list<double> dl = {1.1, 2.2, 3.3, 4.4, 5.5 };