C++学习之路-Lambda表达式

Lambda表达式结构

本质是函数

完整结构:

[capture list](params list) mutable exception ->return type{
			function body
};

其中,各个内容的含义:

  • capture list:捕获列表,捕获表达式外部的变量,相当于函数传参一样
  • params list:参数列表,该表达式可接收的参数,可省略(当表达式不需要外部传参的时候)
  • mutable:用来指定表达式可以修改捕获变量的值,需要时才添加
  • exception:异常设定
  • return type:表达式的返回类型,相当于函数的返回值类型一样(可省略,当表达式内部不返回任何值的时候)
  • function body:跟函数体一样,也就是函数实现

但是表达式,需要一个返回值指向这个表达式,也就是函数指针。通常我们采用auto直接指向,省事。

auto func_ptr = [capture list](params list) mutable exception ->return type{
			function body
};

然后,我们调用这个表达式的时候,就像函数一样:需要传入参数列表

retun type value = func_ptr(params list)

比如,举一个简单的例子:

int a = 10;
int b = 20;

auto Lambda = [a,b](int para1,int para2)mutable->int {
	a = a + para1;
	b = b + para2;
	return a + b;
};
cout << Lambda(1, 1) << endl; //32

把mutable去掉,在表达式内部就不可以修改a或b的值。如果我在函数内部并没有修改a的值,那么mutable就可以省略,如果有修改捕获值的需求,那就得需要加上mutable。

在这里插入图片描述

如果真的想修改a或者b的值,且不想用mutable,那就得采用引用传递了。

auto Lambda = [&a,&b](int s,int v)->int {
	a = a + s;
	b = b + v;
	return a + b;
};

//不用auto的话,就得这么写,交代函数指针的类型
//int (*Lambda)(int,int) 这叫指向函数的指针,必须说明参数列表
int (*Lambda)(int,int) = [&a,&b](int s,int v)->int {
	a = a + s;
	b = b + v;
	return a + b;
};

因为,表达式中的捕获列表默认采用的值传递,也就是说不加引用不加mutable,是直接将a的值传递进来,不会影响外部a的值。

比如,我将a,b的值传入表达式,然后返回a+b,因为是值传递,所以返回的直接是10+20,而不是a+b本身。所以,即使我后来更改了a和b的值,对结果依然不会有影响

int a = 10;
int b = 20;

auto Lambda = [a,b]()->int {
	return a + b;
};

a = 20;
b = 30;

cout << Lambda() << endl; //30

外部变量捕获 [capture list]

重点记录一下外部捕获变量的规则

值捕获

表达式默认的捕获是值捕获,即只捕获变量的值,不会改变其本身

int a = 10;
int b = 20;
auto Lambda = [a,b]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//10,20

引用捕获

当我引用捕获a时,在调用表达式之前,改变a,表达式里面的a也会改变

int a = 10;
int b = 20;
auto Lambda = [&a,b]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//20,20

隐式捕获(默认全部值捕获)

只需在捕获列表里传入‘=’,就会默认全部都是值捕获(表达式内部用到的值)

int a = 10;
int b = 20;
int c = 30;
auto Lambda = [=]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//10,20

隐式捕获(默认全部引用捕获)

默认,表达式内部的变量全部是外部变量的引用,因此,外部更改了变量,里面也会更改。

int a = 10;
int b = 20;
auto Lambda = [&]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//20,30

指定某一个变量是值捕获,其余全是引用捕获

除了a之外的所有出现在表达式内部的变量,都是引用捕获。

int a = 10;
int b = 20;

auto Lambda = [&,a]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//10,30

指定某一个变量是引用捕获,其余全是值捕获

与上面的同理

int a = 10;
int b = 20;

auto Lambda = [=,&a]{
	cout << a << endl;
	cout << b << endl;
};
a = 20;
b = 30;
Lambda();//20,20
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值