一. 什么是Lambda /=4 m4
所谓Lambda,简单的说就是快速的小函数生成。 ]'+PJdA
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, Ldqn<wNnI
j_YpkKhen
{BB#Bh[
=LLix .
>
class filler wyG7SA
{ 6_xPk`m
public : JAEn
72
void operator ()( bool & i) const {i = true ;} gT3i{iU
} ; oTS/z\C"<u
=@BVO@z@
W>[0u3
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: /~=W3lhY
[ H"\<"1o
fviq}.
).IB{+
for_each(v.begin(), v.end(), _1 = true ); NmbA~i
vxN,oa{hf
G!Gbg3:4e5
那么下面,就让我们来实现一个lambda库。 P[Q3z$I}
~\uI&S5
R1A|g=kF
]dvNUD
二. 战前分析 m[l[yUw#
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 8nKZ
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 z _A]mJ
F`C$F!GE
-l)u`f^n|
for_each(v.begin(), v.end(), _1 = 1 ); Q:rQ;/b0/
/* --------------------------------------------- */ Xx)PyO
vector < int *> vp( 10 ); b#
v+_7
transform(v.begin(), v.end(), vp.begin(), & _1); .lbo\v}2W
/* --------------------------------------------- */ LHJ}I5zv
sort(vp.begin(), vp.end(), * _1 > * _2); i"4&UJu1;
/* --------------------------------------------- */ CSu}_$wC#
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); n*yVfI
/* --------------------------------------------- */ SLGo/I*
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); mEh([ZnY
/* --------------------------------------------- */
:oN$w\A
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); jEaU;
q-tm`t*7
^}VAH#c
Qg^Ga0Lf6
看了之后,我们可以思考一些问题: [9c|!w^F
1._1, _2是什么? c}$C=s5 h}
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 l:'\3-2a
2._1 = 1是在做什么? j2dptM3t{
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 Wjf,AjL\
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 J/T$.*X
|:[
[w&R
IXA3G7$)
三. 动工 B:?MMXB
首先实现一个能够范型的进行赋值的函数对象类: ; fOkR+
NA`qC.K
3$TU2-x;g
} ={TVs^
template < typename T > Pjvzefp
class assignment !=/wpsH
{ K*"Wq:T;B
T value; Y<vHL<G
public : cM|!jnKm
assignment( const T & v) : value(v) {} Tl/!Dn
template < typename T2 > 8k.<