一. 什么是Lambda `'k's]Y
所谓Lambda,简单的说就是快速的小函数生成。 _tauhwu
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, @0@'6J04
"=5vgg3
<xh'@592
=ym~=
S
class filler .qU%SmQ^
{ cK}
public : 6;=wuoJi
void operator ()( bool & i) const {i = true ;} mYs->mg1
} ; !E.lyz
[8J}da }
~Sem_U`G
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: ''
A[`,3
MAhPO!e5.
$R#L@iL-
8@C|exAD`
for_each(v.begin(), v.end(), _1 = true ); 4 >tYMyLt0
$!3t$-TSD
gSo(PW)
那么下面,就让我们来实现一个lambda库。 L5N{ie_
e^fKatI1
b+#~N>|
@^4M~F%
二. 战前分析 }T*xT>p^3
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 M&\ ?)yG
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 8J(zWV7 r
fyoB]{$p8
aZ:?(u]
for_each(v.begin(), v.end(), _1 = 1 ); !iz vY
/* --------------------------------------------- */ ^Th"`Av5
vector < int *> vp( 10 ); Bc@r*zb
transform(v.begin(), v.end(), vp.begin(), & _1); 0 Ln5e.&
/* --------------------------------------------- */ 1R~WY'Ed
sort(vp.begin(), vp.end(), * _1 > * _2); 25@j2K (
/* --------------------------------------------- */ (w:ACJ[[
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); O?J:+L(
/* --------------------------------------------- */ M{kh=b)V
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); .nY6[2am
/* --------------------------------------------- */ g4qdm{BL
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); xwp?2,<
C-
Rie[
YaZ"&i
9TN5|x
看了之后,我们可以思考一些问题: ML"P"&~u6
1._1, _2是什么? f?I *`~k
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 &``oZvuB
2._1 = 1是在做什么? T-8nUo}i
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 < 3+&DV-<N
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 Gbm_xEPC
: )*Ge3
Z!l!3(<G.f
三. 动工 2}C>{*}yQ
首先实现一个能够范型的进行赋值的函数对象类: J0W).mD_H
Ck a]F2,
c89vx 9
L;t~rW!1
template < typename T > [cAg'R6
class assignment "LaX_0t)
{ H 1X]tw.
T value; /<pQ!'/G
public : 9F1stT0G%
assignment( const T & v) : value(v) {} |VEAzY|[#
template < typename T2 > [)0 k}
T2 & operator ()(T2 & rhs) const { return rhs = value; } +7OT`e
%q
} ; exKmK!FT
2 3w{h d
cW^)$>A
其中operator()被声明为模版函数以支持不同类型之间的赋值。 i1Sc/
然后我们就可以书写_1的类来返回assignment 17 iq
JJ3JULL2
=0yJ2[R7Do
&