C++11引入了Lambda表达式。Lambda表达式的引入,方便了简短函数的定义,为常用的一次性函数的定义和使用提供了很大的便利。
Lambda表达式实际上是一种匿名函数定义,常用来定义简单和不重复使用的函数。其可使用的外部变量、定义方式等都与常规函数有所不同。
语法结构# Lambda表达式的完整定义结构如下:
auto f = [函数对象参数](函数参数列表) mutable throw(类型)->返回值类型 {函数语句};
Lambda表达式的定义结构分为六个部分:
函数对象参数部分,Lambda表达式的引入部分,用于初始化Lambda表达式,其中[]中可以填入一些标识来指示Lambda表达式如何捕获可以访问的变量。Lambda表达式可以捕获的变量只限于在Lambda表达式定义位置之前出现的变量。标识的放置有以下几种方式:
空白表示不使用任何参数,仅可使用形参列表中的参数。
=(等号),表示使用的变量以值传递的方式捕获,可以直接使用this指针,不再需要显式列举this。
&(与号),表示使用的变量以引用传递的方式捕获,可以直接使用this指针,不在需要显示列举this。
this,表示Lambda表达式可以使用所在类中的成员变量。
变量名,表示在Lambda表达式中,该变量使用以值传递的方式捕获。
&变量名,表示在Lambda表达式中,该变量使用以引用传递的方式捕获。
组合方式,以逗号分隔各个捕获标识,特殊标识的变量按照特殊方式捕获,其余按照默认的标识进行捕获,例如[=, &a, &b]表示a与b两个变量按引用捕获,其余变量按值捕获。
函数参数列表与常规函数定义中的形参列表相同。
mutable关键字,表示可以修改按值传入的变量的副本(不是值本身),类似于不带const关键字的形参。使用mutable关键字后对按值传入的变量进行的修改,不会将改变传递到Lambda表达式之外。
throw(类型)表达式,表示Lambda表达式可以抛出指定类型的异常。
->返回值类型,指示Lambda表达式定义的匿名函数的返回值类型。
函数语句,跟常规函数的函数语句相同,如果指定了函数的返回值类型,函数实现语句中一定需要return来返回相应的类型的值。
基本示例#
基本Lambda表达式的使用##
lang: cpp
int x = 10;
int y = 20;
int z;
z = [=](int a, int b) -> int { return (a + x) * (b + y); }(1, 2);
cout << z << endl;
Result: 242
函数指针的使用##
lang: cpp
typedef int (*Func)(int&, int&);
Func f = [](int& a, int& b) -> int { return a + b; };
关于mutable##
lang: cpp
int x = 1;
int y = 1;
int z;
cout << "x1: " << x << "/t y1: " << y << endl;
z = [=]() mutable -> int
{
int n = x + y;
++x;
++y;
cout << "x2: " << x << "/t y2: " << y << endl;
return n;
}();
cout << "x3: " << x << "/t y3: " << y << endl;
cout << "z: " << z << endl;
输出的结果为:
lang: cpp
x1: 1 y1: 1
x2: 2 y2: 2
x3: 1 y3: 1
z: 2
mutable关键字只能在Lambda表达式定义体之内改变x和y的值,但是这种改变并不能传递到定义体之外。