一. 什么是Lambda P(d4~hS
所谓Lambda,简单的说就是快速的小函数生成。 <jQ?l%\
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, Ja|! fT
,-&ler~[
IR?ICXmtx
Y>{K2#k
class filler
RN'|./N
{
|%g^6RN
public : A/,7%bB1
void operator ()( bool & i) const {i = true ;} wZ,9~P7
} ; hUcG3IOBf
ot]E\g+!
A{Z=[]r1`E
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: /,f*IdB
DHW;*A-
DT8|2"H
>0=` 3X|Y7
for_each(v.begin(), v.end(), _1 = true ); tEf_XBjKV
`B"=\0
+n %uIv
那么下面,就让我们来实现一个lambda库。 m\__Fl
ZTWbe
;M{ @23?`
:kfHILi
二. 战前分析 gXZ.je)NM
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 d%\{,
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 wLPL9
F"#bCnS
[bIdhG
for_each(v.begin(), v.end(), _1 = 1 ); M])Y|}wv8
/* --------------------------------------------- */ ((\s4-
vector < int *> vp( 10 ); 81fpeoNO
transform(v.begin(), v.end(), vp.begin(), & _1); G%
/* --------------------------------------------- */ En&ESWN
sort(vp.begin(), vp.end(), * _1 > * _2); Pq>r|/~_
/* --------------------------------------------- */ {v}f/cu
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); o>W H;EBL
/* --------------------------------------------- */ **d3uc4y
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); 3<1Uq3Pa
/* --------------------------------------------- */ w-2p'u['Z
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); ns9iTU)
znw\Dn?g
@Nn9-#iW
Qa~o'
看了之后,我们可以思考一些问题: 6&S;Nrg9
1._1, _2是什么? (n05MwKu\
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 D+]#qS1q
2._1 = 1是在做什么? CDQ}C=4
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 _{)e\n
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 $*V:;-H
<->Nex
~&4Hc%*IB
三. 动工 qYBoo]}a
首先实现一个能够范型的进行赋值的函数对象类: X#j-Ld{j
Wjn1W;m&g
>c*}Do{lG
!s06uh
template < typename T > B?'`\q)UL
class assignment nPj%EKdY4
{ 8Gzc3
T value; hn#i,XnY
public : ya0L8`q
assignment( const T & v) : value(v) {} !jL|HwlA
template < typename T2 > UB }n=
T2 & operator ()(T2 & rhs) const { return rhs = value; } v=E V5#A
} ; ^6bU4bA
8bLA6qmM\
cu5Yvp
其中operator()被声明为模版函数以支持不同类型之间的赋值。 "jH=O(37
然后我们就可以书写_1的类来返回assignment "G-}
wt+P
\/g.`Pe
o_p#sdt"
eEePK~%c
class holder <RS@,
{ laG@SV
public : l&S2.sC
template < typename T > 1P:r=Rt/
assignment < T > operator = ( const T & t) const
AC@WhL
{ o7)<