C++之lambda
什么是lambda表达式?
一个lambda表达式表示一个可调用的代码单元。我们可以将其理解为一个匿名的内联函数。lambda表达式跟普通函数相比不需要定义函数名,取而代之的多了一对方括号[]。
lambda表达式语法
[capture] (parameters) mutable ->return-type{statement}
说明:
[capture]:捕捉列表,该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用。
(parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略。
mutable:默认情况下,lambda函数总是一个const函数,mutable可
以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)。
->return-type:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导。
{statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量。
我们可以忽略参数列表和返回类型,但必须永远包含捕获列表和函数体。
捕捉列表?
捕捉列表描述了上下文中那些数据可以被lambda使用,以及使用的方式
传值还是传引用。捕捉列表有以下形式:
[var]:以值传递方式捕捉指定的变量var
[&var]:以引用传递的方式捕捉变量var
[=]:以值传递的方式捕捉父作用域中的所有变量(包括this指针)
[&]:以引用传递的方式捕捉父作用域中的所有变量(包括this指针)
[this]:以值传递的方式捕捉当前的this指针
语法上捕捉列表可由多个捕捉项组成,并以逗号分割。例如:
[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所
有变量
[&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量
注意:捕捉列表不运行变量重复传递,否则就会导致编译错误。
[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复
lambda表达式仅能捕捉父作用域中的局部变量。在父作用域以外引用lambda表达式时,捕捉列表必须为空。
参数列表?
与一个普通的函数调用类似,调用一个lambda时给定的实参被用来初始化lambda的形参。通常,实参和形参的类型必须完全相同,但与普通函数不同的是,lambda不能有默认参数。因此,一个lambda调用实参数目永远与形参数目相等。
lambda表达式的作用
在lambda没有引入前,我们只能封装函数来实现,出于函数作用域及运行效率考虑,此函数通常还需加上static和inline关键字。但lambda的引入,其捕捉列表的功能,使我们不用考虑参数个数以及传递方式,而且主调函数结束函数,lambda函数也结束,不会影响命名空间中的其他东西,使代码的实现更加简答,可读性更高。
例如:
#include <vector>
int main()
{
vector<int> v{ 1, 2, 3, 4 };
auto Print = [](vector<int>& v)
{
for(auto e:v)
cout<<e<<" ";
};
// 利用lamb函数打印vector中内容
Print(v);
// 给vector中每个成员*2
for (auto e : v)
e *= 2;
// 检测是否打印成功
Print(v);
return 0;
}