一. 什么是Lambda WT,I~'r=S
所谓Lambda,简单的说就是快速的小函数生成。 C lf;+G0
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, ' F.^ 8/>
Ygk_gBRiC
L>IP!.J]?
bdstxjJ`
class filler X<8|uP4
{ BkB_?^Nv8
public : M}[Q2v\
void operator ()( bool & i) const {i = true ;} h# 4n
} ; {rMf/ RAE
36OQHv;&
SeXgBbGAne
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: 9Zl4NV&B
u]NsCHKlT
c>D~MCNxg
UZs '[pm)
for_each(v.begin(), v.end(), _1 = true ); Jkj7ty.J
9*s8%pL
|
CFG<]
那么下面,就让我们来实现一个lambda库。 y%%VJ}'X!
>gzM-d
n(Nu
:1 qLRr
二. 战前分析 K!CVS7
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 ?1\I/'E9
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 3v_j*wy
#Q7:Mu+
L^t%p1R
for_each(v.begin(), v.end(), _1 = 1 ); DlCN
/* --------------------------------------------- */ B)@Xz<Q
vector < int *> vp( 10 ); rT4Q^t"
transform(v.begin(), v.end(), vp.begin(), & _1); uxL+oP0
/* --------------------------------------------- */ 9~Sa7P
sort(vp.begin(), vp.end(), * _1 > * _2); ]>)shH=Yx
/* --------------------------------------------- */ l[[`-f8j
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); H][TH2H1
/* --------------------------------------------- */
:MF`q.:X
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); kum@cA
/* --------------------------------------------- */ xL_QTj
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); %TN$
."dT6u E
OAq-(_H
5(CInl
看了之后,我们可以思考一些问题: YG0/e#5
1._1, _2是什么? F>{bVPh
VA
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 Xxh^4vKjX
2._1 = 1是在做什么? 2H$](k?
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 ru`7iqcz
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 UNb7WN
T U_'1
JzN "o'
三. 动工 WDxcV%
首先实现一个能够范型的进行赋值的函数对象类: -x6_HibbD
[x7Rq_^
)2y [#Blo
!U@ETo
template < typename T > sT1OAK\^
class assignment U3Gg:onuE
{ [\Wl~
a l
T value; I_f%%N%
public : Zex~ $r
assignment( const T & v) : value(v) {} g0biw?
template < typename T2 > fsOlg9
T2 & operator ()(T2 & rhs) const { return rhs = value; } PtuRXx
} ; 31^/9lb
90+Vw`Gz=
+arh/pd_I
其中operator()被声明为模版函数以支持不同类型之间的赋值。
j7_,V?5z
然后我们就可以书写_1的类来返回assignment r+%3Y:dZE
>)Qq^?U
66>X$nx(z
_)vX_gCi
class holder KF
*F
{ NaoOgZ?
public : _`=qc/-0
template < typename T > ?pJ2"/K
assignment < T > operator = ( const T & t) const Ma?uB8o+~
{ $9\8?gS
return assignment < T > (t); HHw&BN