一. 什么是Lambda VfWU-lJ
所谓Lambda,简单的说就是快速的小函数生成。 72uARF
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, KE>|,Ur
v_M-:e3`
xQLVFgd
@r7ekyO8)
class filler /Kcp9Qx
{ e
]-fb{oVH
public : |q0F*\z3
void operator ()( bool & i) const {i = true ;} X{cFqW7
} ; D6X0(pU0
Cngi5._Lb
PkM]jbLe8
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: ^pgVU&-~]/
n~ w.\939@
}7?n\I+n"
sz;B-1^6
for_each(v.begin(), v.end(), _1 = true ); ykAZP[^'
F|mppY'<J
Y:f"Zx
那么下面,就让我们来实现一个lambda库。 u^2)oL
kAc8[Hn
>6yA+?[:
i7rO5<
二. 战前分析 p;#@#>h
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 \
@XvEx%
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 B^|^hZZ>
vndD#/lXq
K
qK?w*Qw
for_each(v.begin(), v.end(), _1 = 1 ); @fz0-vT,
/* --------------------------------------------- */ 7 ) Q>R
vector < int *> vp( 10 ); :Vdo.uUa
transform(v.begin(), v.end(), vp.begin(), & _1); % YgGw:wZ
/* --------------------------------------------- */ :pz`bFJk
sort(vp.begin(), vp.end(), * _1 > * _2);
l!S}gbM
/* --------------------------------------------- */ |q+3X)Y
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); hIBW$
/* --------------------------------------------- */ 8d|/^U.w~V
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); DIAHIV<
/* --------------------------------------------- */ fHFy5j0H
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); w?eJVi@w{
''p7!V?
prypo.RI
4Nylc.2mi
看了之后,我们可以思考一些问题: 6KH&-ffd
1._1, _2是什么? lftT55Tki
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 z5njblUz
2._1 = 1是在做什么? KOv?p@d
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 @wVq%GG}
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 P5?M"j0/^
B}?$kp
0NB5YQ8_]
三. 动工 ][D/=-
首先实现一个能够范型的进行赋值的函数对象类: V^S` d8?
y)//u:l
77zfRSb+
0:C ^-zrx
template < typename T > $M:Ru@Du2
class assignment $u"*n\k>
{ "pA24Ze
T value; yb/v?q?Fk
public : RyuI2jEy
assignment( const T & v) : value(v) {} NzBX2
template < typename T2 > I_.Jo `lK~
T2 & operator ()(T2 & rhs) const { return rhs = value; } qI=j>x
} ; =|j~*6Hd
ta
=6YffXa_s
其中operator()被声明为模版函数以支持不同类型之间的赋值。 w *Txc}
然后我们就可以书写_1的类来返回assignment _6Z}_SiOl
P#j>hS
=NNA7E7c
XYrZI/R
class holder ABG>W>H-S
{ rCH? R
public : (R{|* :KP
template < typename T > *K#Ci1Q
assignment < T > operator = ( const T & t) const &YpWfY&V