C++11特性之lambda应用

	最近在开发过程中,经常使用到lambda表达式,之前也看过相关的东西,但总感觉用起来有点模糊,所以这次系统的总结下lambda相关东西。
	lambda表达式是C++11的新特性之一,为了更深层次的研究lambda表达式,以下通过代码实验和查阅相关文档进行了详细说明。
	lambda函数的语法定义如下:
	[capture] (parameter)mutable ->return-type{statement}
	[capture]:捕获列表,捕获列表能够捕捉上下文中的变量以供lambda函数使用。但需要注意的是,它捕获的上下文只能是出于父作用域中,后续会详细进行说明。
	(parameter):参数列表。与普通函数的参数列表移植,如果不需要参数传递,则可以连通()一起省略。
	mutable:在默认情况下,lambda函数是一个const函数,加入mutable可以取消其常量性,这个设计到了lambda函数的实现原理,后续会对其进行说明。当使用该修饰符的时,参数列表不可以省略(及时参数为空)。
	->return-type:返回类型。
	{statement}:函数体,和普通函数一样,除了可以使用参数外,还可以使用所有捕获的变量。
	如下都是一个lambda函数:
	(1)[]{}
	(2)auto fun = [&]{int a}{b=a};
	接下来我们根据(2)的形式依次介绍下lambda函数。
	1. []
	捕获列表,捕获列表里面的内容,首先必须确定的是父作用域中的上下文。对于全局变量和静态变量,它是不能捕获的。如:
	#include<iostream>
	using namespace std;
	int qwe = 300;
	void main()
	{
			auto fun2 = [&qwe]()
				{
					qwe = 500;
				};
				cout << qwe << endl;
				system("pause");
	}
	这个时候是报错的,编译就会报错,提示不能捕获静态变量值。
	但我们改为:
	void main()
	{
			auto fun2 = []()
				{
					qwe = 500;
				};
				cout << qwe << endl;
				system("pause");
	}
	它这个时候编译和运行都没问题,打印值也为500,这个问题也困扰了半天,为啥我们显式捕获全局变量不能捕获,但我们去掉&就可以捕获了。这个问题我的思考是这样的:
	对于lambda的底层实现来说,lambda的底层实现就是仿函数,仿函数其实就是重定义了成员函数operator()的一种自定义类型对象,对于一个lambda来说,它对应的仿函数是这样的:
	class lambdafun
	{
	public:
	lambdafun(捕获变量)
	{
				捕获值=捕获变量;
	}
	public:
			type operator(parameter)()const
			{
					函数体。
			}
	private:
				捕获值。
	}
	它对应的lambda函数如下:
	[捕获值](parameter)->return type
	{
			函数体;
	}
	有了这样的对应的关系以后,我们理解这个问题就好理解多了,对于捕获值的类型,lambda现在只支持对父作用域的捕获,对于全局变量或静态变量,因为内存区域所处不同,lambda内部会对其进行一个过滤,对于全局变量直接过滤掉,相当于我们仿函数没有成员变量,但是全局变量对于我们的operator()函数体内是可以查找到的一个变量,所以这就是为啥不能显式捕获,但函数体却可以对其进行使用。
	同时对于[]中为空的时候,我们表示不捕获任何东西。
	[=]对应仿函数的构造函数参数为值传递,但因为operator()默认为const,不能对成员变量进行修改,所以当我们在函数体内部对捕获值进行修改的时候回报错。
	[&]表示为引用传递,此时我们就可以对捕获值进行修改,至于为啥对于一个const成员函数值传递不可以修改,引用传递可以修改,这里暂时不叙述了,这个涉及到了引用的内部实现。
	其实如果我们知道了lambda的内部实现就是一个仿函数以后,用lambda就会得心应手了。
	lambda的一些注意点如下:
	1.lambda函数相比于常规函数来说,更加直观,使用起来也非常简便,代码可读性也很好。同时lambda函数默认是内联的,运行效率也不差。同时也要注意捕获变量为值传递时,其传递的值在lambda函数定义的时候就已经决定了,而按引用传递的捕获变量,其传递的值等于lambda函数调用时候的值。
	2.lambda的mutable我其实觉得是一个可以取消的东西,至少我觉得没有用处,相当于打破了const函数的作用,但同时这个值也传递不出来,没用。如:
	int c = 10;
	auto fun2 = [=]()mutable
	{
		c = 60;
	};
	fun2();
	cout << c << endl;
	system("pause");
	打印得到的值为10;
	3.同时lambda对于STL算法的使用会更加方便。如
	vector<int> num;
	for_each(num.begin(),num.end(),[&](int i)
	{
					if(i<10)
						 num.push_back(i);
	});
	先介绍到这。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值