C++面试难点系列-lamda表达式

简介

lamda表达式是C++11中使用最频繁的特性之一。主要是其比较灵活易用。lamda表达式主要有以下特点:1、声明式的编程风格,匿名定义目标函数和对象,不需要再重新写一个函数;2、避免代码膨胀和分散;3、在需要的时间和地点实现功能闭包,程序更灵活。

用法

语法:

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

capture是捕获列表
params是函数参数
opt是函数选项
ret是返回值
func是函数体

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

  • [] : 表示不捕获任何的变量
  • [&] : 表示按引用捕获,就是会捕获外部作用域的所有变量,当作引用传递进lamda表达式
  • [=] : 表示按值捕获,就是会捕获外部作用域的所有变量,当作值传递进lamda表达式。拷贝的值在lamda表达式中是只读的
  • [=, &foo] : 按值捕获外部作用域的所有变量,按引用捕获foo
  • [bar] : 按值捕获bar,同时不捕获其他的变量
  • [&bar] : 按引用捕获bar,同时不捕获其他的变量
  • [this] : 捕获当前类的this指针,如果是已经使用了&,=,默认就会加上这个捕获选项

params:
参数的使用方法和正常的函数没什么区别,当参数个数为0的时候,可以直接把()省略。

auto func = [](){return 0;}
auto func = []{return 0;}

函数选项:
mutable:可以修改按值传递进来的拷贝
exception:值函数可以抛出异常,可以使用throw抛出整数类的异常

ret
返回值一般可以 直接自动推导出返回值,但是返回的是一个初始化列表的时候,就无法自动推导了,需要手动的写上返回值类型。

在这里插入代码片

函数体都和正常的函数没什么区别,这里就不多赘述。

举例:

class A
{
public:
	void test(int x, int y) {
		auto a1 = []{return mnt;} // error, 捕获列表没写捕获外部变量
		auto a2 = [=]{return mnt + x + y;} // ok
		auto a3 = [&]{return mnt + x + y;} // ok
		auto a4 = [this]{return mnt;} // ok
		auto a5 = [this]{return mnt + x + y;} // error,只捕获了this,并没有其他的x,y变量
		auto a6 = [this, x, y]{return mnt + x + y;} // ok
		auto a7 = [this]{return mnt++;} // ok
		auto a8 = [=]{return x++;} // error,拷贝值的时候,拷贝进去的值无法改变
		auto a9 = [=]()mutable{return x++;} // error,拷贝值的时候,拷贝进去的值无法改变,加上mutable表示可以改变值传递的值
	}
private:
    int mnt = 0;
};

本质

lamda表达式在c++11中被看做是一个带operator()的类,即仿函数。
按照c++11的标准,operator()默认是const类型,一个const成员函数无法修改成员变量的值,mutable的目的就在于消除const属性。
并且对于没有捕获任何变量的lamda表达式,就可以当做是一个函数指针来使用。如果捕获了变量的话就只能作为一个仿函数使用。

void test(int a, int b)
{
	using ptr = void(*)(int);
	ptr p1 = [](int x) {
		cout << x << endl;
	};
	p1(1);

	ptr p2 = [=](int x) {
		cout << x << endl;
	}; // error 此时捕获列表不为空不能当做函数指针来使用
	
	function<void(int)> func1 = [=](int x) {
		cout << x << endl;
	}; // ok
	func1(2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值