一. 什么是Lambda Y7<(_p7
所谓Lambda,简单的说就是快速的小函数生成。 t4<+]]
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, *H~&hs>k
3M5wF6nY[[
I}u&iV`
qkBCI,X_Y
class filler `_!R;f
{ U &RZx&W
public : J
}|6m9k!
void operator ()( bool & i) const {i = true ;} <v3pI!)x
} ; =H8Y
R<;;Ph
t^"8
v3'h
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: J*t_r-z
mZ~f?{
Ca
?d8
FTWjIa/[
for_each(v.begin(), v.end(), _1 = true ); T9bUt |
lsKQZ@LN`
i!yE#zew
那么下面,就让我们来实现一个lambda库。 G$VE
o8Blb
sf8F h
6Cgc-KNbk
$^`@ lyr
二. 战前分析 P.-
`[
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 (: @7IWZf@
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 ftD(ed
"~L$oji
dz1kQzOU*
for_each(v.begin(), v.end(), _1 = 1 ); ))4RgS$
/* --------------------------------------------- */ Wv]ODEd
vector < int *> vp( 10 ); 5IfC8drAs
transform(v.begin(), v.end(), vp.begin(), & _1); zoZ10?ojC
/* --------------------------------------------- */ /i(R~7;?
sort(vp.begin(), vp.end(), * _1 > * _2); ##nC@h@
/* --------------------------------------------- */ yaYJmhG
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); f0
kz:sZ9
/* --------------------------------------------- */ $ EexNz
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); C/MQY:X4
/* --------------------------------------------- */ #Ve@D@d[
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); R)6"P?h._4
]E^)d|_
5A+r^xN
vrIWw?/z?
看了之后,我们可以思考一些问题: ;Q0H7)t:
1._1, _2是什么? OJD!Ar8Q
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 fT{%zJU
2._1 = 1是在做什么? a(lmm@;V<
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 X=V2^zrt
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 8=OpX,t(
:D~J(Y2
@.L/HXu-P
三. 动工 UmG|_7
首先实现一个能够范型的进行赋值的函数对象类: '<xV]k|v
%H4>k#b@$
Rp0^Gwa
Hz j%G>
template < typename T > cVli^*se
class assignment GOD{?#c$
{ v {)8QF]
T value; {xf00/
public : ^.c<b_(=h
assignment( const T & v) : value(v) {} *gOUpbtXa
template < typename T2 > WWT1_&0
T2 & operator ()(T2 & rhs) const { return rhs = value; } (Ta (Y=!uq
} ; Wpc8T="q
%:Z_~7ZR
X'j9l4Ph7
其中operator()被声明为模版函数以支持不同类型之间的赋值。 i5SDy(?r
然后我们就可以书写_1的类来返回assignment ijgm-1ECk3
5]zH!>-F
J~AmRo0!k
p#
|}
o9
class holder (U@$gkUx}G
{ 0<+eN8od.
public : hGRHuJ
template < typename T > XrI$@e*
assignment < T > operator = ( const T & t) const d6)+d9?<