模板之泛化仿函数(二)

来源:互联网 发布:卫浴设计软件 编辑:程序博客网 时间:2024/06/07 14:42

实现 STL 的 BindFirst 功能

假设有个 Functor 取两个整数作为参数,你想将其中一个整数绑定为固定值,只让另一个变化。绑定会产生出一个”只取单一整数“的 Functor,如下:

void f(){        // Define a Functor of two arguments        Functor<void, TYPELIST_2(int, int)> cmd1(something);        // Bind the first argument to 10        Functor<void, TYPELIST_1(int)> cmd2(BindFirst(cmd1, 10));        // Same as cmd1(10,20)        cmd2(20);        Functor<void> cmd3(BindFirst(cmd2,10));        // Same as cmd1(10, 30)             cmd3(30);}
绑定不但可以保存”可调用体“,还可以保存它的部分参数并足部降低调用时刻所需的环境需求。这大大提高了 Functor 的表达能力,因为它可以让你包装函数和参数,无需添加作为”粘胶“之用的代码。

template <class Incoming>class BinderFirst: public FunctorImpl < typename Incoming::ResultType,typename Incoming::ParmList::Tail >{typedef Functor < typename Incoming::ResultType,typename Incoming::ParmList::Tail > Outgoing;typedef typename Incoming::Parm1 Bound;typedef typename Incoming::ResultType ResultType;public:BinderFirst(const Incoming& fun, Bound bound): fun_(fun), bound_(bound){}BinderFirst* Clone() const{return new BinderFirst(*this);}ResultType operator()(){return fun_(bound_);}ResultType operator()(typename Outgoing::Parm1 p1){return fun_(bound_, p1);}ResultType operator()(typename Outgoing::Parm1 p1,typename Outgoing::Parm2 p2){return fun_(bound_, p1, p2);}private:Incoming fun_;Bound bound_;};namespace Private{template <class Fctor> struct BinderFirstTraits;template <typename R, class TList>struct BinderFirstTraits < Functor<R, TList> >{typedef Functor<R, TList> OriginalFunctor;typedef typename TL::Erase < TList, typename TL::TypeAt<TList, 0>::Result >::ResultParmList;typedef typename TL::TypeAt<TList, 0>::Result OriginalParm1;typedef Functor<R, ParmList> BoundFunctorType;typedef typename BoundFunctorType::Impl Impl;};}template <class Fctor>typename Private::BinderFirstTraits<Fctor>::BoundFunctorTypeBindFirst(const Fctor& fun, typename Fctor::Parm1 bound){typedef typenamePrivate::BinderFirstTraits<Fctor>::BoundFunctorTypeOutgoing;return Outgoing(auto_ptr<typename Outgoing::Impl>(new BinderFirst<Fctor>(fun, bound)));}const char* Fun(int i, int j){cout << "Fun(" << i << "," << j << ") called" << endl;return "0";}int main(){Functor<const char*, TYPELIST_2(int, int)> f1(&Fun);Functor<string, TYPELIST_1(double)> f2(BindFirst(f1, 10));f2(15);return 0;}
0 0