Функция computeMean из примера 11.6 подойдет в большинстве случаев, но она имеет одно ограничение: не работает она с такими итераторами ввода, как istream_iterator.

Итераторы istream_iterator и ostream_iterator

Шаблоны классов istream_iterator и ostream_iterator представляют собой специализированные итераторы, определенные в заголовочном файле которые позволяют рассматривать потоки как однопроходные контейнеры.

istream_iterator является итератором ввода, который выступает в роли оболочки такого потока ввода, как cin или ifstream, позволяя использовать его в качестве параметра во многих обобщенных функциях. ostream_iterator является итератором вывода, который позволяет использовать потоки вывода, как будто они являются контейнерами. Использование итераторов istream_iterator и ostream_iterator является хорошей привычкой, так как с их помощью легче создавать повторно используемый программный код

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

Пример 11.7. Более обобщенная функция по расчету среднего значения

#include

#include

#include

using namespace std;

template

Value_T computeMean(Iter_T first, Iter_T last) {

 if (first == last) throw domain_error("mean is undefined");

 Value_T sum;

 int cnt = 0;

 while (first != last) {

  sum += *first++;

  ++cnt;

 }

 return sum / cnt;

)

int main() {

 cout << "please type in several integers separated by newlines" << endl;

 cout << "and terminated by an EOF character (i.e , Ctrl-Z)" << endl;

 double mean = computeMean(

  istream_iterator(cin), istream_iterator());

 cout << "the mean is " << mean << endl;

}

При написании обобщенного программного кода следует, по мере возможности, пытаться пользоваться наиболее общим типом итератора. Это подразумевает, что, когда возможно, вы должны стараться писать обобщенные алгоритмы с единственным проходом по потоку ввода. При таком подходе ваш обобщенный программный код не ограничивается только контейнерами, а может также использоваться с такими итераторами ввода, как istream_iterator. Кроме того, алгоритмы с единственным проходом часто более эффективны.

Возможно, вас удивляет то, что я решил тип, возвращаемый функцией computeMean из примера 11.7, передать в качестве параметра шаблона, а не выводить его из типа итератора. Это сделано по той причине, что обычно статистические расчеты выполняются с более высокой точностью, чем точность значений, содержащихся в контейнере. Так, в программном коде примера 11.7 возвращаемое среднее значение набора чисел целого типа имеет тип double.

<p>11.4. Фильтрация значений, выпадающих из заданного диапазона</p>Проблема

Требуется проигнорировать содержащиеся в последовательности значения, которые располагаются ниже или выше заданного диапазона.

Решение

Используйте функцию remove_copy_if, определенную в , как показано в примере 11.8.

Пример 11.8 Удаление из последовательности элементов, значения которых меньше заданного

#include

#include

#include

#include

using namespace std;

struct OutOfRange {

 OutOfRange(int min, int max) :

  min_(min), max_(max) {}

Перейти на страницу:

Похожие книги