在c++中,如果企图将函数作为参数进行传递的话,都会被立即转换为指向函数的指针。
看一个例子,假设我们有一对函数 f 和 g
int f (int);
int g (int);
我们希望能够使用下面的语句
int (*h) (int) = compose(f, g);
通过 compose 函数将函数 f 和 g 复合,它等价于(*h) (n) 将会等价于 f( g( n ) )。
我们或许会想能不能这样写
//这段代码是错误的!!!
int (*compose(int f(int), int g(int))) (int x)
{
int result(int n) { return f(g(x)) };
return result
}
错误原因主要是一下两个:
(1)c++不支持嵌套函数。
(2)result需要在块作用域之内访问函数 f、g。
实际上我们可以通过函数对象解决这个问题。
int (*compose(int f(int), int g(int))) (int x)
{
int result(int n) { return f(g(x)) };
return result
}
*/
/*
class Intcomp {
public:
Intcomp(int (*f0)(int), int(*g0)(int)): fp(f0), gp(0) { }
int operator() (int n) const {
return (*fp)((*gp)(n));
}
private:
int (*fg)(int);
int (*gp)(int);
};
这样做在原理上可以解决函数复合的问题,我们可以写出下面的代码
int f(int);
int g(int);
int main()
{
Intcomp fg(f, g);
fg(42); //等价于f(g(42))
}
但是我们只能复合函数,却不能复合函数对象。
我们可以通过写一个模板Comp解决它,把类型交给模板去推断吧。
#ifndef COMP_H_INCLUDED
#define COMP_H_INCLUDED
template <typename T, typename G, typename X, typename Y>
class Comp: public Comp_base<X, Y> {
public:
Comp(T f0, G g0): f(f0), g(g0) { }
Y operator() (X x) const {
return f(g(x))
}
private:
T f;
G g;
};
#endif
主函数中:
int main()
{
Comp<int (*)(int), int (*)(int), int, int> fg(f, g);
fg(42); //调用f(g(42))
}