一. 什么是Lambda bV#j@MJ~0
所谓Lambda,简单的说就是快速的小函数生成。 6W;`}'ap
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, 1h)K3cC
Hbu
:HFJ!
;oVOq$ql
aouYPxA`
class filler /WX&UAG
{ c<Q*g
public : }ZiJHj'<
void operator ()( bool & i) const {i = true ;} eV;nTj
} ; Q yQ[H
\y7Gi}nI
C}9|e?R[Rz
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: {q;_Dd
.I^Y[_.G
-Wre4^,v
KWi|7z(L=
for_each(v.begin(), v.end(), _1 = true ); % S>6Q^B
'I r
(4rHy*6
那么下面,就让我们来实现一个lambda库。 7+6I~&x!Lz
M}=fdH
uY3#,
2Z`Jr/
二. 战前分析
"tA.`*
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 fM*aZc*Y
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 ,1vFX$
h 3 J&
]2[\E~^KU
for_each(v.begin(), v.end(), _1 = 1 ); [V5,1dmkI
/* --------------------------------------------- */ ;9Wimf]G,E
vector < int *> vp( 10 ); %8P6l D
transform(v.begin(), v.end(), vp.begin(), & _1); nwDGzC~y<
/* --------------------------------------------- */ $)=`Iai
sort(vp.begin(), vp.end(), * _1 > * _2); AD6 b
/* --------------------------------------------- */ H87k1^}HV
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); !D/W6Ic@
/* --------------------------------------------- */ 9'ky2
]w
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); C9>^!?>
/* --------------------------------------------- */ -Gm}i8;
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); f67pvyy -
~ntDzF
:e}j$vF
_m%Ab3iT~
看了之后,我们可以思考一些问题: v~YGef;D
1._1, _2是什么? )2:U]d%pk
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 6/Z_r0^O
2._1 = 1是在做什么? IhK%.B{dZ
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 "|PX5
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 V.ae 5@;
HisH\z/i5)
UHIXy#+o5
三. 动工 91k-os(4]
首先实现一个能够范型的进行赋值的函数对象类: OY!WEP$F-C
JbXi|OS/
F C=N}5u
#VZ
js`d6
template < typename T > ykxAm\O
class assignment Jl$
X3wE
{ z07:E>D]
T value; A 0;ng2&
public : e_1L J
assignment( const T & v) : value(v) {} W4nhPH(
template < typename T2 > iU#"G" &
T2 & operator ()(T2 & rhs) const { return rhs = value; } }0OQm?xh
} ; S*WLb/R2
'\"5qB
81)i>]
其中operator()被声明为模版函数以支持不同类型之间的赋值。 @U =~c9
然后我们就可以书写_1的类来返回assignment gaE8\JSr
[o
6
J@ 8OU
g}*p(Tp9:
class holder pM*(
kN
{ iN5[x{^t
public : >#Bu [nD%
template < typename T > zN\C
assignment < T > operator = ( const T & t) const KJt6d`ZN
{ +zl[C
return assignment < T > (t); xb&,9Lxd|
} 5BM6Pnle
} ; NezE]'}
]qEg5:yY
Bc<