lambda函数

发布时间:2023年12月31日


lambda 函数,是C++11中新引入的函数式编程语法,lambda函数可以被定义在类中成员函数内部,全局函数的内部。它是一个局部函数(即在函数作用域中定义的函数)。
一般都是定义在函数的内部,底层编译器会把lambda函数编译为仿函数。

定义

lambda函数的语法定义如下:

[capture](parameters) mutable ->retrun-type{statement};

[capture]:捕捉列表。捕捉列表总是出现在lambda函数的开始处。事实上,[]是lambda引出符。编译器根据该引出符判断接下来的代码是否是lambda函数。捕捉列表能够捕捉上下文中的变量以供lambda函数使用。

(parameters):参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号()一起省略。

mutable: mutable 修饰符。默认情况下。lambda函数总是一个const函数,mutable可以取消其常量性。
在使用该修饰符时,参数列表不可以省略(即使参数为空)。

->retrun-type: 返回类型。用追踪返回类型形式声明函数的返回类型。
出于方便,不需要返回值的时候也可以连同符号->一起省略。此外,在返回类型明确的情况下,
也可以省略该部分,让编译器对返回类型进行推导。例如: ->void ; ->int ; ->bool
->retrun-type 是一个整体要省略时都省略。例如:[]->{} //是错误写法

{statement}: 函数体。内容与普通函数一样,不过除了可以使用参数以外,还可以使用所有捕获的变量。

在极端情况下,C++11中最为简略的lambda函数只需要声明为 []{};但是该lambda函数不能做任何事情。

捕捉列表的形式

语法上 捕捉列表由多个捕捉项组成,并以逗号分割。捕捉列表有如下几个形式:
[var] 表示值传递方式捕捉变量var。这是方式变量var,必须是父作用域内的自动变量,捕捉任何非此作用域或者是非自动变量都会编译报错。
[=] 表示值传递方式捕捉所有父作用域及全局作用域的变量(包括this)。
[&var] 表示引用传递方式捕捉变量var。这是方式变量var,必须是父作用域内的自动变量,捕捉任何非此作用域或者是非自动变量都会编译报错。
[&] 表示引用传递方式捕捉所有父作用域及全局作用域的变量(包括this)。
[this] 表示值传递方式捕捉当前的this指针。

注意:父作用域:这里指的是包含lambda函数的语句块。

一些更复杂的捕捉列表组合

[c,&a,&b]: 表示以引用传递方式捕捉变量a和b,值传递方式捕捉变量c。
[=,&a,&b]: 表示以引用传递方式捕捉变量a和b,值传递方式捕捉其他所有变量。
[&,a,this]: 表示以值传递方式捕捉变量a和this,引用传递方式捕捉其他所有变量。

不过值得注意的是,捕捉列表不允许变量重复传递。否则会导致编译时期报错。
[=,a] 这里=已经以值传递方式捕捉了所有变量,再捕捉a重复。
[&,&this] 这里&已经以引用传递方式捕捉了所有变量,再捕捉this重复。

代码演示

演示一

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;
	
	//定义一个lambda函数
	auto totalChilds = [=]() mutable ->int
	{
		int total = girls + boys;
		cout << __func__ << ": total= " << total << endl;
		return total;
	};
	cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}

注意:这里使用了一个auto关键字推导出了totalChilds变量的类型为匿名lambda函数,后续就可以再父函数内使用totalChilds来调用lambda函数使用了。
在这里插入图片描述
通过__func__ 打印输出可以看到在lambda函数内会被打印处operator()。即仿函数的名称。说明了lambda函数也是一种仿函数。

演示二

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;

	auto totalChilds = [=](int a) mutable ->int
	{
		int total = girls + boys + a;
		cout << __func__ << ": total= " << total << endl;
		return total;
	};
	cout << __func__ << ": totalChilds= " << totalChilds(5) << endl;
}

注意: totalChilds中传递的数值5会被传递给lambda函数的形式参数a。
在这里插入图片描述

演示三

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;

	auto totalChilds = [&]() ->int 
	{
		int total = girls + boys;
		cout << __func__ << ": total= " << total << endl;
		return total;
	};
	cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}

注意: 没加mutable,默认就是const,即不能在lambda内修改传递进来的变量的值。但是这个const关键字不能显示的写出来,否则编译报
错。

演示四

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;

	auto totalChilds = [girls, boys]() ->int
	{
		int total = girls + boys;
		cout << __func__ << ": total= " << total << endl;
		return total;
	};
	cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}

在这里插入图片描述

演示五

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;

	auto totalChilds = [&girls, &boys]() ->int
	{
		int total = girls + boys;
		cout << __func__ << ": total= " << total << endl;
		return total;
	};
	cout << __func__ << ": totalChilds= " << totalChilds() << endl;
}

在这里插入图片描述

演示六

int main(int argc, char* argvs[])
{	
	int girls = 3, boys = 6;

	auto totalChilds = [girls, boys]()
	{
		int total = girls + boys;
		cout << __func__ << ": total= " << total << endl;
		//return total;
	};
	totalChilds(); //无返回值
}

在这里插入图片描述

文章来源:https://blog.csdn.net/adminstate/article/details/135315392
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。