其实在研究bind前我也一直很疑惑,我们可以延迟调用函数,却不知道如何传递当时的环境情况,绑定可以,虽然loki只提供了BindFirst,但是递归是loki还有你我都已经达成的共识。
BindFirst接受Functor,而且返回Functor,你可以想像,它一定内部对传入的Functor进行了某种转换、拷贝仰或赋值。我们来看BindFirst函数:
template <class Fctor>
BindFirst(const Fctor& fun,typename Fctor::Param1 bound)

...{
typedef Fctor::BoundFunctorType Outgoing;
return Outgoing(std::auto_ptr<typename Outgoing::Impl>(new BinderFirst<Fctor>(fun,bound)));
}
BindFirst只是一个助手函数,它负责创建一个新的FunctorImpl,而此处的FunctorImpl 接受一个额外的参数:Fctor::Parm1,可以想象,新的Impl一定是内部保存了这个参数,在调用的时候进行的参数传递。
和开发其他FunctorImpl一样,BinderFirst可以被轻易完成,只是你一看记住需要记录一个额外的参数。
template <class Incoming>
class BinderFirst :public FunctorImpl<typename Incoming::ResultType,typename Incoming::Arguments::Tail>

...{
typedef Functor<typename Incoming::ResultType,Incoming::Arguments::Tail> Outgoing;
typedef typename Incoming::Parm1 Bound;
typedef typename Incoming::ResultType ResultType;
public:

BinderFirst(const Incoming& fun,Bound bound) :fun_(fun),bound_(bound)...{}
//...

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_;
};
MCD里对对这段代码解释的不好,而且它的代码可能是直接拷贝loki里的东西,名称空间还在,要详细了解这部分,建议看loki代码这部分。
如你所见,BindFirst是方法,你可以在任何阶段使用它,这有别于类似typelist的编译期推到的思想,这也就是说,运行阶段的任意合法操作(编译期未知行为)都可以使用BindFirst。
int doadd(int a,int b)

...{
return a + b;
}

int _tmain(int argc, _TCHAR* argv[])

...{
Functor<int,LOKI_TYPELIST_2(int,int)> cmd1(doadd);
Functor<int,LOKI_TYPELIST_1(int)> cmd2(BindFirst(cmd1,1));
Functor<int> cmd3(BindFirst(cmd2,1));
cout<<cmd3()<<endl;
Functor<int> cmd4(BindFirst(cmd2,cmd3()));
cout<<"cmd4() = "<<cmd4()<<endl;

for (int i = 0;i < 10; ++i)

...{
Functor<int> cmd5(BindFirst(cmd2,i * i));
cout<<i<<":"<<cmd5()<<endl;
}
return 0;
}