Functor——Impl

在讨论这个问题前,请一定记得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作为构造函数的参数,其实是成员函数模板。

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_;
}
;

依据编译器自动转换支持,我们处理了一般函数的情况,对于转发成员函数的实现方式,我们需要一个额外的对象:

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_;
}
;

这使用了和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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值