Загрузка...

Объекты — функции.


В ряде случаев вместо пердачи алгоритмам функции по имени возникает неодходимость передачи объекта-функции (object_function), кот. представляет собой большую универсальность. К примеру, объект-функция может поддержи¬вать ссылки на наборы данных, определять статические переменные, функции-члены и т.д. Также причиной исползования объектов-функций является скорость. Т.к. код объектов-функций подставляется непостредственно (inline), в результате его выполнение может оказаться более быстрым, чем при повторяющихся вызовах для длинных иттерациях. Технически объект-функция предст-ся любой структурой или классом, перегружающим операции вызова функции.
Для объектов-функций часто исп-ся одна полезная функция accumulate. По умолчанию accumulate суммирует элементы набора данных. Для ее применения необходимо включить заголовок numeric.
Пример:
#define MAX 10
vector <int> v(MAX);
// заполнение вектора некоторыми значениями
for (int i=0; i< MAX; i++ ) v[i]=i+1;
//суммирование элементов вектора
int sum=accumulate (v.begin(), v.end(), 0);
Где аргумент 0 соответствует начальному значению процесса накопления результата и при суммировании значений он обычно д.б. равен 0.
Применяя объект-функции accumulate можно использовать для вычисле¬ния произведения ряда, например факториала.
int product=accumulate(v.begin(), v.end(), 1);

Начальное значение =1, т.к. мы применяем операцию умножения. Объект-функция times <int> (); обеспеичвает функцию accumulate всем необходимым для получения произведения целых чисел.
Генератор – это разновидность объект-функций, кот-я обладает памятью, т.е. она “помнит” значения предыдущего вызова. В следующем примере показано как применять объект-функции для передачи генератора случ. последовательно¬сти алгоритму random_shuffle.
# include <iostream>
# include <algoritm>
# include <vector>
using namespace std;
//перемешиваемые данные
int iarray[10]={1,2,3,4,5,6,7,8,9,10};
vector <int> v(iarray, iarray+10);
//прототипы функций
void Display(vector <int> &vr, const char *s);
unsigned int Randint (unsigned int n);
void main(){
Display(v, “before shuffle:”);
random_shuffle(v.begin(), v.end(), ptrfun(Randint));
Display(v, “after shuffle:”);
}
//выводит содержимое вектора vr
void Display(vector <int> &vr, const char *s){
cout << endl << s << endl;
copy (vr.begin(), vr.end(), iostream.iterator <int> (cout, “ ”));
cout << endl;
// возвращает следующее случайное число по мод. n
unsigned int Randint(unsigned int n){
return random (n);
}
Передача Randint непосредственно по имени не работает, т.к. алгоритм random_shuffle предполагает получение указателя на унарную функцию. Сам объект ptrfun предопределен в stl как экземпляр шаблона pointer_to_unary_function на на унарную функцию.

Загрузка...