一. 什么是Lambda 6xDk3
所谓Lambda,简单的说就是快速的小函数生成。 336ETrG^0
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, s)WA9PiC
~\am%r>
CU|E-XPW
?>;b,^4
class filler [!)HWgx
{ ChK-L6
public : (xo`*Q,+
void operator ()( bool & i) const {i = true ;} LAC&W;pJ"
} ; !yv>e7g^
cAN!5?D\
:E-$:\V0}k
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: H4ie$/[$8
$IQPB_:
*6yY>LW
fnq 3ic"V
for_each(v.begin(), v.end(), _1 = true ); ZiZ @3O6
3t<a3"{9
e%e.|+
那么下面,就让我们来实现一个lambda库。 yBy7d!@2
cg {5\Vl
CT'4.
dU9;sx
二. 战前分析 z I2DQ]
9
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 2-@)'6"n
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 t]SB.ja
<r,5F:
(m'-1wX.
for_each(v.begin(), v.end(), _1 = 1 ); :6o%x0l
/* --------------------------------------------- */ S`vt\g$ dN
vector < int *> vp( 10 ); +rv##Z
transform(v.begin(), v.end(), vp.begin(), & _1); ZP~H!
/* --------------------------------------------- */ [y8(v ~H
sort(vp.begin(), vp.end(), * _1 > * _2); f$FO 1B)
/* --------------------------------------------- */ q;[HUyY,
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); {>
,M
/* --------------------------------------------- */ IM1&g7Qs2
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); Lk|`\I
T
/* --------------------------------------------- */ F'|K>!H
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); =RHtugwy
\i+AMduAo
LilK6K
Dh4Lffy
看了之后,我们可以思考一些问题: y7/4u-_c
1._1, _2是什么? FaCW +9B
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 ftpPrtaP
2._1 = 1是在做什么? <cOjtq,0
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 >>$L
vQ
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 6:wk=#w
Z-lhJ<0/Pa
hqln6m
三. 动工 Pm6U:RL
首先实现一个能够范型的进行赋值的函数对象类: C7F\Y1Wj
mn03KF=n]
hdWV vN
K6-)l
isf
template < typename T > 0\U*
class assignment %Mj,\J!
{ YCE *Dm
T value; oUn+tu:
public : T%oJmp?0
assignment( const T & v) : value(v) {} bM"?^\a&Q