lambda表达式的捕获跟参数差不多,可以是值或者引用。
1.值捕获
与传值参数类似,采用值捕获的前期是变量可以拷贝;与参数不通透的是:被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。
void func(){ int v1 = 1; auto f = [v1] { return v1;}; v1 = 0; auto j = f(); //j为1;f保存了我们创建它时v1的拷贝 }
2.引用捕获
在使用引用捕获的时候,由于lambda保存的是引用,因此值会随着引用变化而变化。
void func(){ int v1 = 1; auto f = [&v1] { return v1;}; v1 = 0; auto j = f(); //j为0;f保存的是v1的引用,而非拷贝 }
在以上两种捕获的方式中,都有着相同的问题和限制:lambda捕获的是局部变量,如果lambda在函数结束后执行,那么这些局部变量就都消失了。
除了上面两种捕获之外,我们还可以采用隐式捕获。
3.隐式捕获
为了指示编译器推断捕获列表,我们可以在捕获列表中写一个&或=。&告诉编译器采用引用捕获,=则为值捕获方式。如:
auto f = [&] {return v1}; auto f = [=] {return v1};
除了&与=,还有以下的捕获列表
[] 空捕获列表
[names] names是一个逗号分隔的名字列表,默认全部都被拷贝
[&] 引用捕获
[=] 值捕获
[&,identifier_list] identifier_list为一个逗号分隔的列表,包含多个来自函数的变量,均采用值捕获方式,而任何隐式捕获的变量都采用引用捕获的方式
[=,identifier_list] identifier_list为一个逗号分隔的列表,包含多个来自函数的变量,均采用引用捕获方式,而任何隐式捕获的变量都采用值捕获的方式