孤独的猫

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

lambda表达式是C++11最重要也是最常用的一个特性之一。

lambda表达式有如下优点

  • 声明式编程风格:就地匿名定义目标函数或函数对象,不需要额外写一个命名函数或者函数对象。以更直接的方式去写程序,有好的可读性和维护性
  • 简洁:不需要额外再写一个函数或者函数对象,避免了代码膨胀和功能分散,让开发者更加集中精力主手边的问题,同时也获取了更高的生产率。
  • 在需要的时间和地点实现功能必报,使程序更灵活

lambda表达式的概念和基本用法

lambda表达式定义了一个匿名函数,并且可以捕获一定范围内的变量,其语法形式可归纳为:

[capture] (params)opt->ret {body;};

lambda表达式可以通过捕获列表捕获一定范围内的变量:

  • [] 不捕获任何变量
  • [&] 捕获外部作用域中所有变量,并作为引用主函数体中使用
  • [=] 捕获外部作用域中所有变量,并作为副本在函数体中使用
  • [=,&foo] 按值捕获外部作用域中所有变量,并按引用捕获foo变量
  • [bar] 按值捕获bar变量,同时不捕获其他变量。
  • [this] 捕获当前类中的this指针,让lambda表达式拥有和当前类成员函数同样的访问权限。如果已经使用了&或者=,就默认添加此选项

例如

auto f=[](int a){ return a+1; }
std::cout << f(1)<<std::endl; //输出:2
可以看到,上面通过一行代码定义了一个小小的功能闭包,用来将输入加1并返回。
需要注意的是,初始化列表不能用于返回值的自动推导:
auto x1=[](int i){ return i; }; //OK,return type is int
auto x2=; }; //error: 无法推导出返回值类型
另外,lambda表达式在没有参数列表时,参数列表时可以省略的。因此像下面的写法都是正确的:
auto f1=;
auto f2=[]{ return 1; }; //省略空参数表

一个容易出错的细节是关于lambda表达式的延迟调用的:
int a=0;
auto f=[=]{ return a; }; //按值捕获外部变量
a +=1; //a被修改
std::cout<<f()<<std::endl; //输出0
虽然通过a +=1,a的值取得了变化,但是因为f中存储的a是按值捕获的,a还是捕获时的值,所以仍然为0

下面看一下它的具体用法

class A
{
public:
	int i_=0;
	
	void func(int x,int y)
	{
		auto x1=[]{ return i_; };                 	//error,没有捕获外部变量
		auto x2=[=]{ return i_+x+y; };            	//OK,捕获所有外部变量
		auto x3=[&]{ return i_+x+y; };            	//OK,捕获所有外部变量
		auto x4=[this]{ return i_+x+y; };         	//OK,捕获this指针
		auto x5=[this]{ return i_+x+y; };			//error,没有捕获x,y
		auto x6=[this,x,y]{ return i_+x+y; };		//OK,捕获this指针,x,y
		auto x7=[this]{ return i_++; };				//OK, 捕获this指针,并修改成员的值		
	};
	
	int a=0,b=1;
	auto f1=[]{ return a; };        		//error,没有捕获外部变量
	auto f2=[&]{ return a++; };				//OK,捕获所有外部变量,并对a执行自加运算
	auto f3=[=]{ return a; };				//OK,捕获所有外部变量,并返回a	
	auto f4=[=]{ return a++; };				//error,a是以复制方式捕获的,无法修改
	auto f5=[a]{ return a+b; };				//error,没有捕获变量b
	auto f6=[a,&b]{ return a+(b++); };		//OK,捕获a和b的引用,并对b做自加运算
	auto f7=[=,&b]{ return a+(b++); };		//OK,捕获所有变量和b的引用,并对b做自加运算
}
posted on 2021-10-12 11:55  孤独的猫  阅读(112)  评论(0编辑  收藏  举报