|
Программирование >> Немодифицирующие последовательные алгоритмы
таблице 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 является прямым итератором, п должно быть
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |