void fcn()
{
int v1 = 42; //局部变量
auto f = [v1] { return v1; };
auto a = f();
cout << a << endl; //a为42
v1 = 0;
auto j = f();
cout << j << endl; //j为42,f保存了我们创建它时v1的拷贝
}
由于被捕获变量的值是在lambda创建时拷贝,因此随后对其修改不会影响到lambda内对应的值,除非捕获的是变量的引用。
如果我们捕获一个指针或迭代器,或采用引用捕获方式,就必须确保在lambda执行时,绑定到迭代器、指针或引用的对象仍然存在,而且需保证对象具有预期的值。一般来说我们因该尽量减少捕获的数据量,来避免潜在的捕获导致的问题。而且如果可能的话,应该避免捕获指针或引用。
当我们混合使用隐式捕获和显示捕获时,捕获列表中的第一个元素必须是一个&或=,也就是说隐式捕获要放在第一个捕获位置,而且,当二者混用时,显示捕获的变量必须使用与隐式捕获不同的的方式。
可变的lambda:如果是值捕获则在参数列表后加关键字mutable,如果是非const引用则可以直接改变,const引用在不能改变。
auto f = [v1] ()mutable { return ++v1; }; // 不能在非可变lambda中改变值捕获
指定lambda返回类型默认情况下,如果一个lambda体包含return之外的任何语句,则编译器假定此lambda返回void。与其他返回void的函数类似,被推断返回void的lambda不能返回值,必须用位置返回类型来指明返回类型:如下:
vector<int> vec{ -1, -2, -3, 4, 56, -67, -23, 32, -90 };
list<int> ilst;
transform(vec.begin(), vec.end(), back_inserter(ilst),
[](int i) ->int { if (i < 0) return -i;
return i; });
书上说没有如果lambda推断返回类型为void时,如果没有位置返回类型而返回了非void类型则会报错,但是不知道为什么我的程序没有报错
transform(vec.begin(), vec.end(), vec.begin(),
[](int i) { if (i < 0) return -i;
return i; });
对于那种只在一两个地方使用的简单操作,lambda表达式是最有用的。如果我们需要在很多地方使用相同的操作,通常应该定义一个函数,而不是多次编写相同的lambda表达式。类似的,如果一个操作需要很多语句才能完成,通常使用函数更好。