一. 什么是Lambda zmf5!77
所谓Lambda,简单的说就是快速的小函数生成。 4VaUa8 D
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, WqY:XE+?\
;csAhkf:S
AWQwpaj-
dm.?-u;C
class filler Ej 'a
G
{ W3*WR,z
public : {
j&|Em]
void operator ()( bool & i) const {i = true ;} j^iH[pN] \
} ; |m k $W$h
j=dHgnVvj
+Z$X5Th
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: !j %)nU
kc|`VB8L
n?Gm 5##
wm*`
for_each(v.begin(), v.end(), _1 = true ); mkj`z
b
|m$ W
8DLR
那么下面,就让我们来实现一个lambda库。 }[D~#Z!k
3$l'>v+5{
z ;y22
yn!LJT[~2
二. 战前分析 c
!P9`l~MQ
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 3Eiy/
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 .b N0!
8dIgw
L V33vy
for_each(v.begin(), v.end(), _1 = 1 ); W|D'S}J
/* --------------------------------------------- */ g6QkF41nG
vector < int *> vp( 10 ); JYm@Llf)$
transform(v.begin(), v.end(), vp.begin(), & _1); XuR!9x^5
/* --------------------------------------------- */ jc Ie<i;
sort(vp.begin(), vp.end(), * _1 > * _2); xC<OFpI\
/* --------------------------------------------- */ NO`a2HR$
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); )dC%g=dtc
/* --------------------------------------------- */ G0> 'H1 Z
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); =kZPd>&L
/* --------------------------------------------- */ go2:D#mf
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); \^N9Q9{7]
6=A++H@
j*W]^uT,
5>}L3r>a;
看了之后,我们可以思考一些问题: o~<fw]y
1._1, _2是什么? oc\rQ?
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 }4_izKS
2._1 = 1是在做什么? pgU54Ef
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 O+.V,`O
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 4d0PW#97.
CXCU5-
Sr2c'T"
三. 动工 }Ax$}#
首先实现一个能够范型的进行赋值的函数对象类: QE<63|
RG:ct{i
I9SO}a2p
8C4Tyms
template < typename T > |4X:>Ut]
class assignment K.l?R#G`,F
{ *1; <xeVD
T value; lOd[8|/
public : N ?V5gi
assignment( const T & v) : value(v) {} m'aw`?
template < typename T2 > T{sw{E*
T2 & operator ()(T2 & rhs) const { return rhs = value; } K Qub%`n
} ; vx!nC}f"k`
&z1r$X.AW
ms;Lu-UR
其中operator()被声明为模版函数以支持不同类型之间的赋值。 4"l(rg
然后我们就可以书写_1的类来返回assignment "vU:qwm
cQ3Dk<GZ
5IdmKP|
nV:.-JR
class holder T`a [~:
{ /MQd [03]
public : eg?vYW
template < typename T > ; M"hX
assignment < T > operator = ( const T & t) const g[H7.
{ mjBXa
return assignment < T > (t); u@|GQXC
} m&2<?a}l
} ; 7F|T5[*l
0p
Lb<&