一. 什么是Lambda 9|9/8a6A
所谓Lambda,简单的说就是快速的小函数生成。 H#bu3*'
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, Ej`G(
YJwffV}nd
"(:8$Fb
W#9LK
Jj
class filler D,s[{RW+q
{ j9=)^?
public : M!\6Fl{ b
void operator ()( bool & i) const {i = true ;} 1w>G8
} ; I>>X-}
A{52T]9X
"+BuFhSLf
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: l+O\oD?-
q4u-mM7#7
NbUibxJ
'_xa>T}
for_each(v.begin(), v.end(), _1 = true ); H"|oI|~
.r-kH&)"GU
T{ /\q 5
那么下面,就让我们来实现一个lambda库。 kgRgHkAH~
TI3@/SB>
;B"S*wYMN
4rNuAK`2
二. 战前分析 mzTM&@
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 SJ:Wr{ Or3
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 it=ir9
0"`|f0}c
<U""CAE
for_each(v.begin(), v.end(), _1 = 1 ); $60]RCu
/* --------------------------------------------- */ y Xi$w.gr
vector < int *> vp( 10 ); 2iWxx:e
transform(v.begin(), v.end(), vp.begin(), & _1); kn6X
I*
/* --------------------------------------------- */ [2zS@p
sort(vp.begin(), vp.end(), * _1 > * _2); [b@9V_
/* --------------------------------------------- */ qBWt(jY
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); 0 oHnam
/* --------------------------------------------- */ "H)D~K~*
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); rh(77x1|(G
/* --------------------------------------------- */ j}$Q`7-wB1
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); &n&ndq
J<7nOB}OD
Qx[
nR/
7vK}aOs0
看了之后,我们可以思考一些问题: >)iCKx
1._1, _2是什么? d##'0yg
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 ILXV yU
2._1 = 1是在做什么? U~{sJwB
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 OW8"7*irT
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 sVT\e*4m}
~ny4Ay$#
k&\ 6SK/
三. 动工 uVV;"LVK~
首先实现一个能够范型的进行赋值的函数对象类: cvQMZ,p
WiclG8l
Q
,)}t
VtC1TZ3-7
template < typename T > 1$~W~O
class assignment 9\W }p\c
{ %$I@7Es>
T value; -OV!56&
public : =lqGt.x
assignment( const T & v) : value(v) {} IH0qx_;P&
template < typename T2 > 06S-3bis
T2 & operator ()(T2 & rhs) const { return rhs = value; } &5F@u
IA
} ; I^fKZ^]8P
<