一. 什么是Lambda ~[8n+p+&X
所谓Lambda,简单的说就是快速的小函数生成。 Sg%h}]~
在C++中,STL的很多算法都要求使用者提供一个函数对象。例如for_each函数,会要求用户提供一个表明“行为”的函数对象。以vector<bool>为例,如果想使用for_each对其中的各元素全部赋值为true,一般需要这么一个函数对象, JJ:p A_uX
SjosbdD
Vz.G!*>Dg
_V2^0CZ
class filler ak,KHA6u
{ %x'}aTa
public : e
p jb
void operator ()( bool & i) const {i = true ;} 7e NLs
} ; mM9a T0_w
\;XDPC j
VSx9aVPkC
这样实现不但麻烦,而且不直观。而如果使用lambda,则允许用户使用一种直观和见解的方式来处理这个问题。以boost.lambda为例,刚才的问题可以这么解决: Q};n%&n&
fe!eZiE
'/OcJVSR
mpr_AL!ZO~
for_each(v.begin(), v.end(), _1 = true ); epicY
m+UWvUB)
G2$<Q+UYs?
那么下面,就让我们来实现一个lambda库。 jz,K>
_0cCTQE
A<h^.{
ai7R@~O:_k
二. 战前分析 "D\>oFu
首先要说明的是,我并没有读过boost.lambda或其他任何lambda库的代码,因此如代码有雷同,纯属巧合。 --fRh N>
开始实现以前,首先要分析出大致的实现手法。先让我们来看几段使用Lambda的代码 Bd'X~Vj<
?"F9~vx&G
ol0i^d*9F
for_each(v.begin(), v.end(), _1 = 1 ); nxWm
/* --------------------------------------------- */ @4t_cxmD
vector < int *> vp( 10 ); = K)[3mXX
transform(v.begin(), v.end(), vp.begin(), & _1); {EfA#{x
/* --------------------------------------------- */ QdIx@[+WOq
sort(vp.begin(), vp.end(), * _1 > * _2); \gsJ1@
/* --------------------------------------------- */ bO i-QD
int b = * find_if(v.begin, v.end(), _1 >= 3 && _1 < 5 ); 6i+<0b}!/
/* --------------------------------------------- */ ~dO+kD
for_each(vp.begin(), vp.end(), cout << * _1 << ' \n ' ); gt(^9t;
/* --------------------------------------------- */ Pz^C3h$5_
for_each(vp.begin(), vp.end(), cout << constant( ' \n ' ) << * _1); b(IZ:ekZ5
(himx8Uml2
<x8I<K
&4O2uEW0
看了之后,我们可以思考一些问题: YpOcLxFL
1._1, _2是什么? hv
显然_1和_2都满足C++对于标识符的要求,可见_1和_2都是对象。 +\doF
2._1 = 1是在做什么? |(%=zb=?X
既然_1是一个对象,那么_1的类必然重载了operator=(int)。那么operator=返回什么呢?该函数所返回的对象被传入for_each的第3个参数,可见其返回了一个函数对象。现在整个流程就很清楚了。_1 = 1调用了operator=,其返回了一个函数对象,该函数对象能够将参数1赋值为1。 tk)JE^'
Ok,回答了这两个问题之后,我们的思路就很清晰了。如果要实现operator=,那么至少要实现2个类,一个用于产生_1的对象,另一个用于代表operator=返回的函数对象。 nTtE+~u
oE.Ckz~*d
8J#U=qYei
三. 动工
Vp7d
首先实现一个能够范型的进行赋值的函数对象类: MY60%
eRqPZb"6MR
J$W4AT
T@Bu Fr`]<
template < typename T > _Sg "|g
class assignment gSa !zQN6
{ {/FdrS
T value; D6dliU?k
public : Z2U6<4?1%
assignment( const T & v) : value(v) {} upLjkQ)_
template < typename T2 > XU`ly3!
T2 & operator ()(T2 & rhs) const { return rhs = value; } &^UT
} ; PNo9.-@G
ew \WV"
qeW.~B!B
其中operator()被声明为模版函数以支持不同类型之间的赋值。 EI9;J-c
然后我们就可以书写_1的类来返回assignment x8xz33
<NEz{ 1Z
85f:!p
5DpvMhc_
class holder !kG |BJ$j
{ naro
public : v.&c1hK