Так и сделано в известной библиотеке Boost.
Листинг 12.15. Класс-адаптер для указателя на унарную функцию
template<class Result, class ТуреР> class pointertounaryfunction { public:
explicit pointertounaryfunction(Result (*PF)(TypeP)): Pfun(PF) { } Result operator()(TypeP arg) const { return (Pfun(arg)); } private:
Result (*Pfun)(TypeP); // указатель на функцию
};
// функция-оболочка
template<class Result, class TypeP>
inline
pointertounaryfunction <Result, TypeP> ptrfun(Result (*PF)(TypeP))
{ return (pointertounaryfunction<Result, TypeP>(PF)): }
Возвращаемый результат тоже сделан параметром, поэтому с данным кдассом и шаблоном функции-оболочки правильно работает любая функция, принимающая один параметр и возвращающая результат любого типа. Например, мы можем умножить элементы контейнера на 2, использовав приведенную ранее функцию twice():
int a[10] = { 1.2,3,4,5,6,7,8.9,0}; int b[10] = {0};
copy_if(a, a+10, b, ptrfun(twice));
for(int i = 0; i < 10; ++i) cout << b[i] « '
cout << endl;
Результат, естественно, совпадает с тем, который получался при непосредственной передаче указателя на функцию. Тогда возникает вопрос: а зачем опять «городить огород» с функторами, если можно передавать просто указатель? Во-первых, работать с объектами удобней и эффективней, чем с указателями, во-вторых, в данном случае вызов стал самодокументированным — явно показано, что мы передаем указатель на функцию.
Точно так же мы можем написать класс-адаптер для бинарных функций и соответствующую функцию-оболочку (листинг 12.16).
Листинг 12.16. Класс-адаптер для указателя на бинарную функцию
template<class Result, class TypePl, class TypeP2> class pointertobinaryfunction { public:
explicit // конструктор
pointertobinaryfunction(Result (*PF)(TypePl, TypeP2)): Pfun(PF) {}
Result operator()(TypePl Left, TypeP2 Right) const
{ return (Pfun(Left, Right)); }
private:
Result (*Pfun)(TypePl, TypeP2); // указатель на функцию
};
// функция-оболочка
template<class Result, class Argl, class Arg2>
Листинг 12.16 {продолжение) inline
pointertobinaryfunction<Result, Argl, Arg2> ptrfun(Result (*PF)(Argl, Arg2))
{ return (pointertobinaryfunction<Result, Argl, Arg2>(PF)); }
Надоели вирусы, тогда вам нужен - http://www.programcatalog.ru/catalog/detail/eset_nod32_smart_security/.
Использовав классы-фиксаторы, мы вполне можем передать в copyi f () любую бинарную функцию, например приведенную выше функцию greatef ():
copy_if(a, а+10, b, bindright(ptrfun(greatef), 4)); Естественно, все работает, как и прежде. |