C++ lambda表达式

1、lambda基本概念   ———《C++ Primer 5th》

       一个 lambda 表达式表示一个可调用的代码单元。我们可以将其理解为一个未命名的内联函数。与任何函数类似,一个 lambda 具有一个返回类型、一个参数列表和一个函数体。但与函数不同,lambda 可能定义在函数内部。一个lambda表达式具有如下形式

[capture list] (parameter list) -> return type {function body}

其中,capture lis(捕获列表)是一个lambda所在函数中定义的局部变量的列表(通常为空);return type、parameter list 和 function body与任何普通函数一样,分别表示返回类型、参数列表和函数体。但是与普通函数不同,lambda必须使用尾置返回来制定返回类型。

我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体

auto f = [] {return 42;};    //此例中,我们定义了一个可调用对象f,它不接受参数,返回42
 lambda的调用方式与普通函数的调用方式相同,都是使用调用运算符:

cout << f() <<endl;     //打印42
在lambda中忽略括号和参数列表等价于制定一个空参数列表。此例中,当调用 f 时,参数列表是空的。如果忽略返回类型,lambda 根据函数体中的代码推断出返回类型。

如果函数体只是一个reutrn 语句,则返回类型从返回的表达式类型推断而来。否则,返回类型为void

2、捕获列表

    虽然lambda可以出现在一个函数中,但不能想当然认为他就可以使用所在函数的变量。例:

int n = 3;
	auto f = [] {
		cout << n << endl;   //错误,n 未定义
	}
必须使用捕获列表捕获 n 才能使用(如需捕获多个变量,用逗号‘,’隔开)

int n = 3;
	int m = 4;
	auto f = [n,m] {
		cout << n << endl;
		cout << m << endl;
	};
	f();
3、值捕获

被捕获的变量的值实在lambda创建时拷贝,而不是调用时拷贝

int n = 3;
	auto f = [n] {
		cout << n << endl;
	};
	n++;
	f();
输出结果为3   创建时n为3 随后对其修改不会影响到lambda内对应的值

4、引用捕获

        int n = 3;
	auto f = [&n] {
		cout << n << endl;
	};
	n++;
	f();
输出结果为4

5、隐式捕获

可以通过在捕获列表中写一个 & 或者 = 让编译器根据lambda体重的代码来推断我们要使用哪些变量。 & 告诉编译器采用引用捕获方式,= 表示采用值捕获方式

        int n = 3;
	auto f = [=] {
		cout << n << endl;
	};
	n++;
	f();
结果为3

        int n = 3;
	auto f = [&] {
		cout << n << endl;
	};
	n++;
	f();
结果为4

6、混合隐式捕获和显式捕获

当我莪们混合使用隐式捕获和显式捕获时,捕获列表中的第一个元素必须是一个 & 或者 =  。此符号指定了默认捕获方式为引用或值。

显式捕获的变量必须使用与隐式捕获不同的方式

int n = 3;
	int m = 4;
	auto f = [&,m] {
		cout << "n=" << n << ends;
		cout << "m=" << m << endl;
	};
	n++;
	m++;
	f();
输出结果为 n=4 m=4;   n为引用传递,m为值传递

7、可变lambda

默认情况下,对于一个值被拷贝的变量,lambda不会改变其值。如果希望能改变一个被捕获的变量的值,就必须在参数列表尾部加上关键字 mutable 。因此,可变lambda 不能省略参数列表

int m = 4;
	auto f = [m]()mutable{
		cout << "m=" << ++m << endl;
	};
	f();
输出结果为 m=5     如果没有mutable  第三行将会报错。 没有参数列表()   单独加mutable 也是不可以的


引用捕获的变量可否修改依赖于此引用指向的是一个const类型还是一个非const类型

int n = 4;
	const int &m = n;
	int &m2 = n;
	auto f = [&]{
		cout << "m=" << ++m << endl;   //报错
		cout << "m2=" << ++m2 << endl; //正确
	};
	f();


  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值