C++11中Lambda表达式的基本用法和总结

前言

对于Lambda表达式:其实本质就是一个函数,其用法也和函数差不多,只不过它和函数的区别在于,lambda表达式可以在函数里面定义,而函数不可以嵌套定义,并且在形式上也有一定的区别;
一般我们把lambba表达式,当作一种匿名函数去使用,也就是说:这个函数是没有名称的;


lambda的基本形式

基本形式如下:
[捕获列表](参数列表)->返回类型{函数体};

int main()
{
	[]{
		cout<<"这是最基本的lambda表达式的形式"};
	return 0;
}

lambda表达式的参数列表如果没有,那么就可以省略;
返回值如果没有也可以省略,甚至有时候返回值类型很简单,编译器也会自动推到出,意思是你可以省略;

在这里插入图片描述


说:lambda表达式和函数基本没什么区别,还说时匿名函数,那么我们就尝试以下用函数指针形式去调用;

int main
{
	void(* p)() = [ ]{
		cout<<"用函数指针形式调用lambda表达式"<<endl;
	};
	p(); //调用lambda表达式
	return 0;
}

测试:调用成功;
在这里插入图片描述


当然:还可以结合auto去推到lambda表达式的类型;

int main
{
	auto p = [ ]{
		cout<<"用函数指针形式调用lambda表达式"<<endl;
	};
	p(); //调用lambda表达式
	return 0;
}

省略形参参数,省却返回值的lambda表达式写法

	//一个无返回值类型,无参数类型的函数 
	void fun (){
		//函数体逻辑实现
	}
	
	//以下三种lambada表达式都等价这个函数模样
	//1.
 	[ ]{
		//lambda表达式逻辑实现
	};
	//2.
	[ ]( ) {
		//lambda表达式逻辑实现
	};
	//3.
	[ ]()-> void {
			//lambda表达式逻辑实现
	};

对于有参数,有返回值的 lambda表达式写法

//一个返回值int ,参数列表int 和 int 的函数
	int add(int x,int y){
		return x+y;
	}
	
	//lambada表达式等价这个函数模样
	
 	[ ](int x,int y)->int{
		return x+y;
	};	

总结:
1.lambda的[ ]{} 都不可以省略;
2. lambda的调用方式和普通函数以用,可以通过函数指针()去调用;
3. lambda没有返回值可以省略-> ,没有参数列表可以省略( );


lambda中的捕获列表[ ]的常用方式

对于lambda表达式[ ] 中括号里面的东西,可以添加捕获列表的值:
捕获列表表示:捕获lambda表达式外部作用域的变量
而这个外部作用域如何理解呢?lambda{ } 花括号外一层的作用域咯;


捕获列表可以有好几种形式:
1. [ ]:表示不捕获任何外部作用域的变量(当然这是非静态变量);

int main 
{
	int a = 10;
	auto p = [] //[ ] 里面没有任何捕获变量,表示不捕获外部的任何变量
	{
		//试图获取a的值,但是是不合法的,因为[ ]没有捕获任何变量
		cout<<a<<end; //非法
	}
	return 0;
}

假如变量在静态区的变量,如全局变量,和静态变量都是直接可以在lambda表达式中使用,不需要在[ ] 里面捕获静态区的变量


2. [ &]:表示捕获外部作用域所有的变量,并且以引用的形式捕获

int main 
{
	int a = 10;
	int b = 20;
	auto p = [&] //[ &] 里面有&符号,表示捕获外部的任何变量,以引用的方式捕获
	{
		//试图获取a的值,
		cout<<"a = "<<a<<endl;//合法
		cout<<"b = "<< b<<end; //合法
		
		//通过引用捕获的变量,可以在lambda表达式中修改
		a++; //合法
		b+=10; //合法
	}
	cout<<"在lambda表达式修改了a = "<<a<<endl; //结果为11;
	cout<<"在lambda表达式修改了b = "<<b<<endl; //结果为30;
	return 0;
}

3.[ = ]:表示捕获外部作用域的所有变量,但是以值得方式捕获,并且该变量不可以在lambda表达式里面修改,修改就会报错,只有只读得功能;

int main 
{
	int a = 10;
	int b = 20;
	auto p = [=] //[ =] 里面有&符号,表示捕获外部的任何变量,以值的方式捕获
	{
		//试图获取a的值,
		cout<<"a = "<<a<<endl;//合法
		cout<<"b = "<< b<<end; //合法
		//
		通过值方式捕获的变量,不可以在lambda表达式中修改
		a++; //非法合法
		b+=10; //非法合法
	}
	cout<<"在lambda表达式修改了a = "<<a<<endl; //结果依旧是10
	cout<<"在lambda表达式修改了b = "<<b<<endl; //结果依旧是20;
	return 0;
}

4.[this]:捕获this指针,一般用于类里面,为的是:可以使lambda表达式里可以使用类的成员函数和成员变量;

class A
{
private:
	int _i;
public:
	void print(int x,int y)
	{
		auto p = [this]{  
		//注意:lambda表达式中无法使用形参x,y因为该lambda表达式并没有捕获该形参变量x和y
		cout<<x<<y<<endl; //非法	
			return _i; //由于有this被捕获,所以可以使用类的成员变量
		};
		cout<<p()<<endl;
	}
};

注意:当我们类中的lambda的捕获列表是 & = 时候,是默认添加this捕获的,因为& = 的含义就是捕获外部作用域所有变量,而这里的外部作用域指的就是lambda表达式 { }`外的类里面的作用域;


5.[变量名1,变量名2,...]:单独写变量名的表示单独捕获外部作用域的变量,以值的方式捕获,并且变量在lambda表达式中无法修改值;
[&变量名1,&变量名2,...]::以引用方式单独捕获外部变量,并且该值可以在lambda表达式中修改;

class A
{
private:
	int _i;
public:
	void print(int x,int y)
	{
		auto p = [this,x,&y]{  
		//lambda表达式中使用形参x,y因为该lambda表达式捕获该形参变量x和y
		cout<<x<<y<<endl; //合法	
		y++; //合法,以引用方式捕获
		cout<<y<<endl;	
			return _i; //由于有this被捕获,所以可以使用类的成员变量
		};
		cout<<p()<<endl;
	}
};   

6.[=,&变量名1,&变量名2,...]:默认以值的方式捕获外部所有变量,而单独以引用方式捕获单独的变量;
[=,&变量名1,&变量名2,...]:默认以引用方式捕获外部所有变量,而单独以值的方式捕获单独的变量;


lambda表达式中mutable关键字

mutable:关键字表示可修改的,在lambda表达式中使用,表示可以修改以值捕获的变量

int main()
{
	int a =10;
	auto p = [a]()mutable{
	a++; //由于有mutable关键字,所以这里的a由不可以修改,变成可以修改
	}
	cout<<a<<endl; //结果为10
	return 0;
}

注意使用mutable关键之,即使lambda表达式没有参数,也需要加上( ),不可以省略;


lambda作为形参传参的用法

对于lambda表达式来说,最常用的就是作为形参传递了,类似于函数指针传参一样,本身lambda表达式就是一个匿名的函数对象,所以说,函数名可以做的,lambda表达式都可以做,但是具体用法就不演示了,只要你觉得你书写一个函数,需要函数指针传参,那么就可以考虑lambda表达式的使用,lambda表达式是一种编程习惯,看你用不用而已;
当然lambda表达式的优点也很明显:可维护性强,可以书写简明代码,阅读性好;

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

呋喃吖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值