Программирование >>  Немодифицирующие последовательные алгоритмы 

1 ... 8 9 10 [ 11 ] 12 13 14 ... 78


таблице find служит примером для входных итераторов в столбце Каким алгоритмом используется.

Вспомним, как мы использовали алгоритм сору (также упомянутый в рассмотренной таблице) в разделе 1.6:

copy(v.begin() , v.endO, L.beginO);

Чтобы увидеть, как это согласуется с нашей таблицей, заметим, что приемник копирования L является списком, который определяет итераторы, относящиеся к двунаправленной категории. Для L достаточно использовать выходные итераторы, но двунаправленные итераторы поддерживают все операции выходных итераторов, так что проблем не возникает. Так как алгоритм сору требует выходной итератор в качестве третьего аргумента, он не будет применять операторы -, +, -, <, <=, >= и > к итераторам, ссылающимся на элементы списка I; также он не будет читать что-либо из I, исполняя операции вроде д: = *i. Однако он воспользуется противоположной операцией *i = х, чтобы записывать копируемые значения в L.

Потоковые итераторы: использование функции сору для ввода и вьгаода

Мы можем применить алгоритм сору для вывода, как показано в следующем фрагменте:

const int N = 4;

int a[N] = {7, б, 9, 2};

copy(a, a+N, ostream iterator<int>(cout, ));

Мы также можем определить переменную-итератор i для использования в качестве третьего аргумента функции сору. Это достигается заменой вызова сору следующими двумя операторами:

ostream iterator<int> i(cout, ); copy(а, a+N, i);

В любом случае в поток стандартного вывода cout будут выведены числа 7, 6, 9 и 2, как если бы мы написали

for (int* р=а; р!= a+N; р++) cout *р ;

Для ввода мы можем использовать аналогичный прием, написав

istream iterator<int, ptrdiff t>(file)

где/г7е является потоком ввода. Это длинное выражение можно, например, употребить вместо v.beginQ, которое мы использовали бы для копирования элементов из контейнера v. Если опустить file в приведенной строчке, то получим выражение



istream iterator<int, ptrdiff t>()

которое нужно применить вместо v.end(),TaK как это выражение служит для обозначения конца файла. Например, пусть у нас есть файл example.txt со следующим содержанием:

10 20 30 40 50

Известно, что файл содержит только целые числа (разделенные пробелами), но мы не знаем заранее, сколько целых чисел находится в файле. Следующая программа читает целые числа из этого файла и показывает их на экране; условная компиляция используется для совместимости с ВС5, который требует наличия второго аргумента для шаблона istream iterator.

11 copyio.cpp: Используем алгоритм сору для ввода-вывода.

#include <fstream> #include <iostream> #include <iterator> #include <vector> using namespace std;

#if defined! BORLANDC ) && BORLANDC == 0x530

Для BC5.3:

typedef istream iterator<int,

char,

char traits<char>, ptrdiff t>

istream iter; #elif defined! BORLANDC ) Для BC5.2:

typedef istream iterator<int, ptrdiff t> istream iter; #else Для VC5.0:

typedef istream iterator<int> istream iter; #endif

int main()

{ vector<int> a;

ifstream file( example.txt ); if (file.failO )

{ cout Cannot open file example.txt.\n ; return 1;

copy(istream iter(file), istream iter(),

inserter (a, a.beginO)); copy(a.begin0 , a.end(),



В стандарте С++ принята функция distance с двумя аргументами вместо трех. Поэтому для компилятора, отвечающего стандарту, следует писать: dist = distance(iO, i) вместо dist = 0; distance(iO, i, dist). - Прим. переводчика.

#if defined! BORLANDC ) && BORLANDC == 0x530

ostream iterator<int, char,

char traits<char> >(cout, ));

#else

ostream iterator<int>(cout, ));

#endif

cout endl; return 0;

Поскольку эта программа не принимает во внимание структуру входного файла, вывод состоит только из одной строчки:

10 20 30 40 50

Мы вернемся к потоковым итераторам в разделе 6.6.

Операции с итераторами

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

int п, dist;

... i и iO являются итераторами произвольного доступа

iO = i; i += n;

dist = i - iO; dist == n Вместо этого мы можем использовать функции advance и distance: int n, dist;

... i и iO являются итераторами, но

необязательно произвольного доступа

iO = i;

advance(i, n); dist = 0;

distance(iO, i, dist); dist == n

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



1 ... 8 9 10 [ 11 ] 12 13 14 ... 78

© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки.
Яндекс.Метрика