C++11引入了Lambda表达式。Lambda表达式的引入,方便了简短函数的定义,为常用的一次性函数的定义和使用提供了很大的便利。
Lambda表达式实际上是一种匿名函数定义,常用来定义简单和不重复使用的函数。其可使用的外部变量、定义方式等都与常规函数有所不同。
#语法结构# Lambda表达式的完整定义结构如下:
auto f = [函数对象参数](函数参数列表) mutable throw(类型)->返回值类型 {函数语句};
auto是C++11新引入的关键字,主要用来自动推断变量的类型,Lambda表达式返回一个函数指针,可以用一般的函数指针定义式来指示类型,但是在C++11中,使用auto更为简便。调用Lambda定义的函数,可以直接使用以下语句来调用:
f(实参列表);
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;
最后输出结果为242。Lambda表达式在定义之后可以直接使用()进行调用。
##函数指针的使用##
lang: cpp
typedef int (*Func)(int&, int&);
Func f = [](int& a, int& b) -> int { return a + b; };
这种方式定义的f跟前面用auto定义的f是一致的。调用方法也跟平常的函数指针一致。
##关于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的值,但是这种改变并不能传递到定义体之外。
来源:oschina
链接:https://my.oschina.net/u/219594/blog/284689