C++11 Lambda语法
2023-06-06
11
0
从软件开发的角度讲,以lambda概念为基础的“函数式编程”(Functional Programming)与命令式编程(Imperative Programming)、面向对象编程(Object-orientated Programming)等并列的一种编程范例。
C++11中的lambda
C++ 11 中的 Lambda 表达式用于定义并创建匿名的函数对象,以简化编程工作。
int a = 1, b = 2;
auto totalab = [](int x, int y) ->int{ return x + y; };
int total = totalab(a, b);
上面的例子中我们定义了一个 lambda函数,该函数接受2个参数(int x,int y),并且返回其int型的和
int{return x+y;}。
从上例可以看出,lambda和普通相比,不需要定义函数名,取而代之的多了一对方括号[]。
labmbda的语法
[capture][parameters] mutable -> return->type{statement}
- [capture]:捕捉列表。捕捉列表总是出现在lambda函数的开始。[]是lambda引出符,编译器根据该引出符判断接下来的代码是否是lambda函数。捕捉列表能捕捉上下文中的变量以供lambda函数使用。具体的方法在下文中再述。
- [parameters]:参数列表。与普通函数的参数列表一致。如果不需要参数传递,则可以连同括号()一起省略。
- mutable:mutable修饰符。在默认的情况下,lambda函数总是一个const函数,mutable可以取消其常量属性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
- return->type:返回类型。用追踪返回类型形式声名函数的返回类型。出于方便,不需要返回值时可以连同符号->一起省略。此外在返回值类型明确的情况下,也可以省略该部分,由编译器对返回值类型进行自行推导。
- {statement}:函数体。内容与普通函数一样,不过除了可以使用参数外,也可以使用所有捕获的变量。
最简单的lambda
在lambda函数定义中,参数列表和返回值类型都是可选的,而捕捉列表和函数体都可能为空,所以最简单的lambda函数就是
[]{};
不过这个lambda函数不能做任何事情。
lambda捕捉列表
捕捉列表描述了上下文中哪些数据可以被lambd使用,以及使用方式(以值的传递方式或引用传递的方式)。
为了说明,我们先看以下代码:
int a = 1, b = 2;
auto totalab = [a,&b]() ->int{ return a + b; };
int total = totalab();
我们使用捕捉列表捕捉参数a,b,这时函数就不再需要进行参数的传递。其中a以值的方式捕足,b以引用的方式捕捉。
捕捉其实就是相当于函数参数的传递方式。
捕捉列表的几种形式
- []。没有任何函数对象参数。
- [=]。函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是值传递方式(相当于编译器自动为我们按值传递了所有局部变量)。这里的所有范围就是父作用域的变量(包括this)。
- [&]。函数体内可以使用 Lambda 所在范围内所有可见的局部变量(包括 Lambda 所在类的 this),并且是引用传递方式(相当于是编译器自动为我们按引用传递了所有局部变量)。
- [this]。函数体内可以使用 Lambda 所在类中的成员变量,即表示值传递方式捕捉当前的this指针。
- [a]。将 a 按值进行传递。按值进行传递时,函数体内不能修改传递进来的 a 的拷贝,因为默认情况下函数是 const 的,要修改传递进来的拷贝,可以添加 mutable 修饰符。
- [&a]。将 a 按引用进行传递。
- [a,&b]。将 a 按值传递,b 按引用进行传递。
- [=,&a,&b]。除 a 和 b 按引用进行传递外,其他参数都按值进行传递。
- [&,a,b]。除 a 和 b 按值进行传递外,其他参数都按引用进行传递。