一. 什么是Lambda QV?\?9(  
所谓Lambda,简单的说就是快速的小函数生成。 *d,SI[c%e  
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, \J1Jn~  
 Mb$&~!  
  b,SY(Ce~g  
 -Tz/ZOJ  
   class  filler 1h)I&T"kZ  
   { nnr(\r~   
  public : ,&l>^w/  
   void   operator ()( bool   & i)  const    {i  =   true ;}  uV%7|/fD  
 } ;  8c~b7F
\  
  a&y%|Gs^f  
 /u#uC(Uwl
  
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: pLk?<y  
 >TtkG|/U-T  
  wt)tLMEv  
 m\jp$  
 for_each(v.begin(), v.end(), _1  =   true );  meIY00  
  L{\B9b2  
 $=H\#e)]Ug  
那么下面,就让我们来实现一个lambda库。 Lww0 LH
>   
 9nd'"$  
  seq
S*^7  
 *K0CUir|  
二. 战前分析 [QL)6Xr  
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 vT[%*)`  
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 D+"5R5J",  
  /4=O^;  
 e'7!aysj  
 for_each(v.begin(), v.end(), _1  =   1 ); #M8"b]oh6  
   /* --------------------------------------------- */  eR5swy&  
 vector < int *>  vp( 10 );  2;6p2GNSh  
 transform(v.begin(), v.end(), vp.begin(),  & _1);  "CLd_H*)c  
  /* --------------------------------------------- */  h^[K= J  
 sort(vp.begin(), vp.end(),  * _1  >   * _2); Zx`hutCv  
  /* --------------------------------------------- */  5$zC,g*#  
  int  b  =   * find_if(v.begin, v.end(), _1  >=   3   &&  _1  <   5 ); t|%iW%m4  
   /* --------------------------------------------- */  e
`_	[+y  
 for_each(vp.begin(), vp.end(), cout  <<   * _1  <<   ' \n ' ); r$.ek\D5  
  /* --------------------------------------------- */  k*lrE4::a  
 for_each(vp.begin(), vp.end(), cout  <<  constant( ' \n ' )  <<   * _1); odj|"ZK  
   _>&zhw2  
  BU])@~$  
 qFvtqv2  
看了之后,我们可以思考一些问题: rF
 7EO%,  
1._1, _2是什么? )!M:=}."  
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 }{9E~"_[  
2._1 = 1是在做什么? LI(Wu6*Y  
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 Yo:>m*31  
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 uZW1
:cx  
 	H\)on"  
 6K*7%8Y/G  
三. 动工 2:2rwH }e  
首先实现一个能够范型的进行赋值的函数对象类: G~YV6??  
 ^$yr-p%-  
  b/ur!2yr  
 Ku&0bXP  
  template < typename T >  6C) G  
  class  assignment +h[$\_y  
   { 5H?`a7q	N  
  T value; Q0nSOTQ  
  public : ~f){`ZJc  
  assignment( const  T &  v) : value(v)  {}  Ok
O;V6`  
  template < typename T2 >  Ks!.$y:x  
   T2 &   operator ()(T2  & rhs)  const    {  return  rhs  =  value; }  3LX<&."z  
 } ;   2<Ub[R  
  :^?ZVi59j  
 ,R*ru*   
其中operator()被声明为模版函数以支持不同类型之间的赋值。 .qF@
}dO  
然后我们就可以书写_1的类来返回assignment ,uuQj]Dac+  
 0UlaB
sv  
  4JP01lq'\  
 Dth<hS,2J  
   class  holder ^=Up UB  
   { 7uxy<#Ar  
  public : l=bB,7gL  
  template < typename T >  J;'?(xO3\  
  assignment < T >   operator = ( const  T &  t)  const  
sx(yG9  
     { %VSST?aUvX  
    return  assignment < T > (t); !]5F2~"v  
  }  g4%x7#vz0  
 } ;  &