在讨论这个问题前,请一定记得Functor的定义,尤其是内部几个typedef,因为我们在使用这些类型,如果忘记这个,将不太容易理解。
根据Bridge模式,我们应有class FunctorHandler : public FunctorImpl;而它应该在初始化Functor的时候被初始化,如此如何定义Functor的构造函数以及如何尽可能多的通过构造函数推测类型是我们写简洁代码不可忽视的一环。
template
<
typename R,
class
TList
>
template < typename Fun >
Functor < R,TList > ::Functor( const Fun & fun)
:spImpl_( new FunctorHandler < Functor,Fun > (fun))
... {
}
template < typename Fun >
Functor < R,TList > ::Functor( const Fun & fun)
:spImpl_( new FunctorHandler < Functor,Fun > (fun))
... {
}
第二组template作为构造函数的参数,其实是成员函数模板。
FunctorHandler内部肯定要保存fun,同时要提供operator()只可能一个被用到的诸多转发调用集,我们如此定义FunctorHandler类,通过首先了解Functor的构造式,FunctorHandler不难理解:
template
<
class
ParentFunctor,typename Fun
>
class FunctorHandler : public FunctorImpl < typename ParentFunctor::ResultType,typename ParentFunctor::ParmList >
... {
public:
typedef typename ParentFunctor::ResultType ResultType;
FunctorHandler(const Fun& fun):fun_(fun)...{}
FunctorHandler* Clone() const
...{ return new FunctorHandler(*this);}
ResultType operator()()
...{ return fun_(); }
ResultType operator()(typename ParentFunctor::Parm1 p1)
...{ return fun_(p1); }
ResultType operator()(typename ParentFunctor::Parm1 p1,typename ParentFunctor::Parm2 p2)
...{ return fun_(p1,p2); }
private:
Fun fun_;
} ;
class FunctorHandler : public FunctorImpl < typename ParentFunctor::ResultType,typename ParentFunctor::ParmList >
... {
public:
typedef typename ParentFunctor::ResultType ResultType;
FunctorHandler(const Fun& fun):fun_(fun)...{}
FunctorHandler* Clone() const
...{ return new FunctorHandler(*this);}
ResultType operator()()
...{ return fun_(); }
ResultType operator()(typename ParentFunctor::Parm1 p1)
...{ return fun_(p1); }
ResultType operator()(typename ParentFunctor::Parm1 p1,typename ParentFunctor::Parm2 p2)
...{ return fun_(p1,p2); }
private:
Fun fun_;
} ;
依据编译器自动转换支持,我们处理了一般函数的情况,对于转发成员函数的实现方式,我们需要一个额外的对象:
template
<
class
ParentFunctor,typename PointerToObj,typename PointerToMemFn
>
class MemFunHandler : public FunctorImpl < typename ParentFunctor::ResultType,typename ParentFunctor::ParmList >
... {
public:
typedef typename ParentFunctor::ResultType ResultType;
MemFunHandler(const PointerToObj& pObj,PointerToMemFn pMemFn)
:pObj_(pObj),pMemFn_(pMemFn)...{}
MemFunHandler* Clone() const ...{ return new MemFunHandler(*this); }
ResultType operator()()...{ return ((*pObj_).*pMemFn_)(p1); };
ResultType operator()()...{ return ((*pObj_).*pMemFn_)(p1,p2); }
private:
PointerToObj pObj_;
PointerToMemFn pMemFn_;
} ;
class MemFunHandler : public FunctorImpl < typename ParentFunctor::ResultType,typename ParentFunctor::ParmList >
... {
public:
typedef typename ParentFunctor::ResultType ResultType;
MemFunHandler(const PointerToObj& pObj,PointerToMemFn pMemFn)
:pObj_(pObj),pMemFn_(pMemFn)...{}
MemFunHandler* Clone() const ...{ return new MemFunHandler(*this); }
ResultType operator()()...{ return ((*pObj_).*pMemFn_)(p1); };
ResultType operator()()...{ return ((*pObj_).*pMemFn_)(p1,p2); }
private:
PointerToObj pObj_;
PointerToMemFn pMemFn_;
} ;
这使用了和FunctorHandler类似的策略,我们可以一致的使用Functor类,只不过多了一个参数。
注意编译器对template T中类型T的推测,如果用T构建类,那你要在使用的地方显示提供T的详情的,如果是成员函数使用,那编译器可以直接根据数据推测类型,当然,手动指定类型是允许的。这是上边两段代码中Fun类型可以被编译器自动推测到的原因。
注意“位于class本体外的member template定义式”问题。思考构造函数的策略,比较使用方法可能比较容易理解这些东西。
void
TestFunction(
int
i,
double
d)
... {
cout<<"TestFunction("<<i<<","<<d<<") called"<<endl;
}
Functor < void ,LOKI_TYPELIST_2( int , double ) > cmd(TestFunction);
cmd( 2 , 4.5 );
class MyClass
... {
public:
void Eat()...{cout<<"Yes,Eat it"<<endl;}
void Speak()...{cout<<"I am in MyClass"<<endl;}
} ;
MyClass mc;
Functor <> cmd1( & mc, & MyClass::Eat);
Functor <> cmd2( & mc, & MyClass::Speak);
cmd2();
cmd1();
... {
cout<<"TestFunction("<<i<<","<<d<<") called"<<endl;
}
Functor < void ,LOKI_TYPELIST_2( int , double ) > cmd(TestFunction);
cmd( 2 , 4.5 );
class MyClass
... {
public:
void Eat()...{cout<<"Yes,Eat it"<<endl;}
void Speak()...{cout<<"I am in MyClass"<<endl;}
} ;
MyClass mc;
Functor <> cmd1( & mc, & MyClass::Eat);
Functor <> cmd2( & mc, & MyClass::Speak);
cmd2();
cmd1();