Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
OOP.doc
Скачиваний:
13
Добавлен:
25.04.2019
Размер:
1.34 Mб
Скачать

Ifstream ifile ("example.In"); ofstream ofile ("example.Out");

...

copy (istream_iterator<int, ptrdiff_t> (ifile),

istream_iterator<int, ptrdiff_t> (),

ostream_iterator<int> (ofile) );

Здесь открываются два файла example.in и example.out и затем содержимое первого копируется во второй. Копирование выполняется стандартным алгоритмом (шаблоном) copy, заголовок которого имеет вид:

template <class InputIterator, class OutputIterator>

OutputIterator copy(

InputIterator first, InputIterator last, OutputIterator result );

Алгоритму copy передаются 3 параметра. Первые два – входные итераторы – задают диапазон контейнера, в котором находятся входные данные. Третий определяет позицию в выходном контейнере, с которой нужно выполнять перезапись.

При конструировании входных итераторов используются три параметра. Первый из них определяет входной контейнер, второй задает тип читаемых значений, а третий (в примере значение ptrdiff_t) указывает на тип «разности между указателями», характерный для текущей модели памяти программы. Для создания выходного итератора нужны два параметра, первый из которых выходной контейнер, а второй – тип записываемых значений. Конструкторы итераторов istream_iterator, ostream_iterator не используют первый параметр шаблона, поскольку потоки здесь задаются через параметр функционального вызова.

При работе с входными и выходными итераторами есть ряд ограничений:

  • разыменованный выходной итератор можно указывать только в левой части оператора присваивания;

  • повторная запись значений в одну и ту же позицию выходного итератора запрещена;

  • выходной итератор не может быть последовательно увеличен в два и более раз без промежуточной записи в его позицию значения;

  • значение выходного итератора может иметь только одну копию в заданной сфере действия;

  • из равенства двух входных итераторов не следует, что равны и значения, на которые они ссылаются.

Однонаправленные итераторы позволяют последовательно перебирать элементы контейнера от его начала к концу и поддерживают те же операции, что и входные итераторы. Разница между ними и входными итераторами состоит в том, что для двух однонаправленных итераторов R и S справедливо правило: из R==S следует ++R==++S. Различие по отношению к выходным итераторам заключается в неограниченном числе присваиваний, а также в возможности использовать разыменованный однонаправленный итератор справа от символа присваивания.

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

vector<int> v (3, 1);

v.push_back (7); // v: 1 1 1 7

vector<int>::iterator i = find_linear(v.begin(), v.end(), 7);

if (i != v.end()) cout << *i;

else cout << "элемент не найден";

Алгоритм find_linear определяется шаблоном следующего вида:

template<class ForwardIterator, class T>

ForwardIterator find_linear(ForwardIterator first,

ForwardIterator last, T& value)

{

while (first != last) if (*first++ == value) return first;

return last;

}

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

Ниже дан пример использования двунаправленных итераторов для сортировки списка пузырьковым методом.

Пример

list<int> l;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]