一. 什么是Lambda WQL\y3f5
所谓Lambda,简单的说就是快速的小函数生成。 .-oxb,/
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, ^pF&`2eD
OGg># vj,s
ww $
w\i\Wp,FP
class filler };jN\x?&q
{ #S*/bao#
public : A5R<p+t6
void operator ()( bool & i) const {i = true ;} n+q!l&&
} ; q[W
0 N>
4UvZ)^r
,UGRrS
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: ^c4@(]v'G
S:oi<F
|G,tlchprs
5l 2 ?
for_each(v.begin(), v.end(), _1 = true ); YS@ypzc/
O%!!w
^N;.cY
那么下面,就让我们来实现一个lambda库。 <[\`qX
Bb^;q#S1
[] `&vWZ
W~~7C,!
二. 战前分析 vAh6+K.e
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 S^>,~R.TX
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 C|).;V&
lpeEpI/gM
,p2s:&"
for_each(v.begin(), v.end(), _1 = 1 ); o9%)D<4M
/* --------------------------------------------- */ [nc4{0 aT'
vector < int *> vp( 10 ); &d+Kg0 :
transform(v.begin(), v.end(), vp.begin(), & _1); : $Y9jR
/* --------------------------------------------- */ $M lW4&a|
sort(vp.begin(), vp.end(), * _1 > * _2); 3U.88{y
/* --------------------------------------------- */ 'y2nN=CN
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); YY)s p%
/* --------------------------------------------- */ m~P CB_ifW
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); l(u.I2^o
/* --------------------------------------------- */ */|lJm'R
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); O[s{ Gk'>
7/ysVWt
I)cFG{~L
6@e+C;j=
看了之后,我们可以思考一些问题: D 38$`j
1._1, _2是什么? &7b|4a8B%
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 6c"0})p
2._1 = 1是在做什么? i2YuOV!
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 fA<[f
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 *:t|qgJI#+
XZJ+h,f
P 8>d6;o($
三. 动工 ;04Ldb1{|3
首先实现一个能够范型的进行赋值的函数对象类: 8lb%eb]U
oCi=4#g%7
Xr2ou5zAn
4.h=&jz&
template < typename T > ~ !
3I2
class assignment 3k#/{Z
{ U.XNv-M
T value; \"^w'ng
public : T[uiPs/xD
assignment( const T & v) : value(v) {} ]*FVz$>XM
template < typename T2 > [}8|R0KF
T2 & operator ()(T2 & rhs) const { return rhs = value; } PBxCx3a{
} ; VUYmz)m5
K]|> Et`
.J.-Mm`.
其中operator()被声明为模版函数以支持不同类型之间的赋值。 PSVc+s[Q+V
然后我们就可以书写_1的类来返回assignment ;SaX;!`39+
k.^coI5
}_;!hdYq
\XM^oE#G
class holder 2fS[J'-o
{ 8&~~j7p,
public : X
9%'|(tL
template < typename T > ~r$jza~o(
assignment < T > operator = ( const T & t) const ,0~9dS
{ IWveW8qJ
return assignment < T > (t); %4
XJn@J
} *
Y7jl#7
} ; &q