На этом шаге мы рассмотрим потоковые итераторы вывода.
Потоковые итераторы вывода записывают присваиваемые значения о выходной поток данных. Это позволяет напрямую выводить результаты работы алгоритмов в потоки данных через стандартный интерфейс итераторов. Реализация потоковых итераторов вывода основана на тех же принципах, что и реализация итераторов вставки. Единственное различие заключается в том, что присваивание нового значения преобразуется в операцию вывода оператором <<. В таблице 1 перечислены операции потоковых итераторов вывода.
Выражение | Описание |
---|---|
ostream_iterator<T>(ostream) | Создание потокового итератора вывода для потока данных ostream |
ostream_iterator<T>(ostream,delim) | Создание потокового итератора вывода для потока данных ostream с разделением выводимых значений строкой delim (параметр dellm относится к типу const char*) |
*iter | Фиктивная операция (возвращает iter) |
iter1 = value | Записывает value в поток данных ostream: ostream<<value (после чего выводится разделитель delim, если он задан) |
++iter | Фиктивная операция (возвращает iter) |
iter++ | Фиктивная операция (возвращает iter) |
При создании потокового итератора вывода необходимо указать выходной поток данных, в который должны записываться данные. В необязательном аргументе можно передать строку, которая должна выводиться между отдельными значениями. Без разделителя элементы будут выводиться непосредственно друг за другом.
Потоковые итераторы вывода определяются для типа элемента Т:
namespace std { template <class T, class charT = char, class traits = char_traits<char_T> > class ostream_iterator; }
Необязательные второй и третий аргументы шаблона определяют тип используемого потока данных.
Следующий пример демонстрирует использование потоковых итераторов вывода.
//--------------------------------------------------------------------------- #include <vcl.h> #include <iostream> #include <iterator> #include <vector> #include <algorithm> #include <conio.h> //необходимо для getch() #pragma hdrstop //--------------------------------------------------------------------------- #pragma argsused using namespace std; std::string ToRus(const std::string &in) { char *buff = new char [in.length()+1]; CharToOem(in.c_str(),buff); std::string out(buff); delete [] buff; return out; } int main(int argc, char* argv[]) { // Создание потокового итератора вывода для потока cout // - выводимые значения разделяются символом новой строки ostream_iterator<int> intWriter(cout,"\n"); // Запись элементов через обычный интерфейс итераторов *intWriter = 42; intWriter++; *intWriter = 77; intWriter++; *intWriter = -5; // Создание коллекции с элементами от 1 до 9 vector<int> coll; for (int i=1; i<=9; ++i) { coll.push_back(i); } // Запись всех элементов без разделителей cout << ToRus("Элементы без разделителей:\n"); copy (coll.begin(), coll.end(), ostream_iterator<int>(cout)); cout << endl; // Запись всех элементов с разделителем " <" cout << ToRus("Элементы c разделителеm \"<\":\n"); copy (coll.begin(), coll.end(), ostream_iterator<int>(cout," < ")); cout << endl; getch(); return 0; } //---------------------------------------------------------------------------
Результат выполнения программы выглядит так:
Рис.1. Результат работы приложения
Разделитель относится к тину const char*, поэтому при передаче объекта типа string необходимо преобразовать его к правильному типу вызовом функции c_str(). Пример:
string delim; . . . . ostream_iterator<int>(cout,delim.c_str());
На следующем шаге мы рассмотрим потоковые итераторы ввода.