一. 什么是Lambda O~7p^i}
所谓Lambda,简单的说就是快速的小函数生成。 #g5't4zqx
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, eh8<?(eK
@B}&62T
Yb,G^+;
S(q4OQB{
class filler
^XjvJa
{ j@kRv@
public : ;,[EJR^CI
void operator ()( bool & i) const {i = true ;} 1q;I7_{ 2
} ; 853]CK<
PW(_yB;
?S;et2f
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: ~:'gvR;x
?h>(&HjWV
Gl3 `e&7
=|DkD-
O
for_each(v.begin(), v.end(), _1 = true ); $i5G7b
s.k`];wo
S^_JC
那么下面,就让我们来实现一个lambda库。 N^@%qUvT]
ur,V>J<5A
gK] T}
'Q^G6'(SaK
二. 战前分析 7KYF16A4
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 v=8~ZDY
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 x_>"Rnv:K
C5W- B8>
O V0cr
for_each(v.begin(), v.end(), _1 = 1 ); ?Mgt5by
/* --------------------------------------------- */ ^@l5u=
vector < int *> vp( 10 ); xLGTnMYd
transform(v.begin(), v.end(), vp.begin(), & _1); RMs1{64:
/* --------------------------------------------- */ Rqv+N]
sort(vp.begin(), vp.end(), * _1 > * _2); T`0`]z !~
/* --------------------------------------------- */ Mz%d_
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); btkMY<o7
/* --------------------------------------------- */ EHE6-^F
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); *(_ON$+3
/* --------------------------------------------- */ -h.3M0
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); t 's5~
A=l?IC@O
AH ?MJKY@Z
Z:}2F^6
看了之后,我们可以思考一些问题: ]2u7?l
1._1, _2是什么? =#PudF.\
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 a*e|>p DO
2._1 = 1是在做什么?
t}* qs
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 QvyUd%e'5A
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 {BwN4r46
_3g %F
yD=)&->Ra
三. 动工 Jq=>H@il
首先实现一个能够范型的进行赋值的函数对象类: Qcy+ {j]
rkER`
d,E/9y\e
OHXeqjhy
template < typename T > ygu?w7
class assignment //@sktHsw(
{ GO&R