На этом шаге мы рассмотрим получение ссылки с помощью алгоритма for_each.
Благодаря алгоритму for_each() хлопоты с реализацией объекта функции на базе подсчета ссылок для получения его итогового состояния оказываются излишними. Алгоритм for_each() обладает уникальной особенностью - он возвращает свой объект функции (другие алгоритмы этого делать не могут). Это означает, что вы можете получить информацию о состоянии объекта функции, проверяя возвращаемое значение алгоритма for_each().
Следующая программа хорошо поясняет, как использовать возвращаемое значение алгоритма for_each(). В ней вычисляется среднее арифметическое числовой последовательности.
//--------------------------------------------------------------------------- #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; } template <class T> inline void PRINT_ELEMENTS (const T& coll, const char* optcstr="") { typename T::const_iterator pos; std::cout << ToRus(optcstr); for (pos=coll.begin(); pos!=coll.end(); ++pos) { std::cout <<*pos <<' '; } std::cout << std::endl; } // Объект функции для вычисления среднего арифметического class MeanValue { private: long num; // Счетчик элементов long sum; // Сумма всех значений элементов public: // Конструктор MeanValue () : num(0), sum(0) { } // "Вызов функции" // - обработка очередного элемента последовательности void operator() (int elem) { num++; // Увеличение счетчика sum += elem; // Прибавление значения } // Возвращение среднего арифметического double value () { return static_cast<double>(sum) / static_cast<double>(num); } }; int main(int argc, char* argv[]) { vector<int> coll; // Вставка элементов от 1 до 8 for (int i=1; i<=8; ++i) { coll.push_back(i); } PRINT_ELEMENTS(coll,"Исходный вектор:\n"); // Вычисление и вывод среднего арифметического MeanValue mv = for_each (coll.begin(), coll.end(), // Интервал MeanValue()); // Операция cout << ToRus("Среднее арифметическое: ") << mv.value() << endl; getch(); return 0; } //---------------------------------------------------------------------------
Вызов MeanValue() создает объект функции, который подсчитывает количество элементов и вычисляет сумму их значений. Передача этого объекта при вызове for_each() обеспечивает его вызов для каждого элемента контейнера coll:
MeanValue mv = for_each (coll.begin(), coll.end(), MeanValue());
Объект функции, возвращенный алгоритмом for_each(), присваивается mv, поэтому после вызова можно запросить информацию о его состоянии в виде mv.value(). В итоге программа выводит следующий результат:
Рис.1. Результат работы приложения
Класс MeanValue можно дополнительно усовершенствовать, определив автоматическое преобразование к типу double. В этом случае среднее арифметическое, вычисленное for_each(), можно будет напрямую использовать в программе.
На следующем шаге мы рассмотрим предикаты и объекты функций.