10.3lambda表达式笔记

与参数不同被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝
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表达式。类似的,如果一个操作需要很多语句才能完成,通常使用函数更好。


 
posted @ 2018-07-09 20:46  Lucky小黄人^_^  阅读(126)  评论(0编辑  收藏  举报