原文地址:http://blog.csdn.net/u012945598/article/details/24603251
“ [捕获列表] ”
首先我们观察一下上图中的第一个lambda表达式与第三个lambda表达式的捕获列表部分的区别。
可以看到,上图的第一个表达式中捕获列表为空 [ ],而第三个表达式中的捕获列表中包含了一个等号 [=]。
下面我们再观察一下上图中第一个与第三个lambda表达式的函数体内都使用到了哪些变量。
可以看到,第一个表达式中所有的变量,均是在Lambda表达式中定义的(log除外,因为log函数包含在头文件中),
而在第三个表达式中所使用到的sprite1,sprite2等变量,并不是在lambda表达式中定义的,而是当前函数中或是当前类中的变量。
那么我们就可以总结出,在Lambda表达式的函数体内,是不能够访问到外部的变量的,如果想要使用函数体外定义的变量,就需要将它们进行"捕获",上图第三个lambda表达式采用的正是“值捕获”,与它对应的另外一种为“引用捕获”。
[ ]:空捕获列表,即lambda表达式不能够使用所在函数中的变量
[=]:值捕获,即lambda表达式可以以拷贝的方式访问到函数中变量的值
[&]:引用捕获,即lambda表达式中所使用的其所在函数中的变量均是引用方式
当我们不希望在捕获的时候将所有的变量都捕获的时候,我们可以使用如下的方式进行捕获,例如:
[=sprite1,&sprite2]
这里我们仅仅捕获了两个变量,第一个变量是以值拷贝的方式捕获,第二个是以引用方式捕获,变量与变量之间用逗号分隔。
正常情况下,如果一个变量是值拷贝,Lambda不能改变它的值,如果我们希望改变一个值拷贝的变量的值,就需要在参数列表前加上关键字mutable
例如:
auto s1=10;
auto s2=[=s1](){return ++s1};//错误,因为s1是值拷贝,不能改变s1的值
auto s2=[=s1]() mutable {return ++s1};//正确