C++ 11 引入了 lambda 表达式,可以快速方便的定义匿名函数。在其他高级语言中,lambda 很早就引入了,例如 C#。
[capture list] (params list) mutable exception-> return type { function body }
一个 lambda 表达式可以由如下几个部分组成。
- capture list:捕获外部变量列表
- params list:形参列表
- mutable 指示符(可选):用来说是否可以修改捕获的变量
- exception(可选):异常设定
- return type(可选):返回类型
- function body:函数体
Lambda表达式可以使用其可见范围内的外部变量,但必须明确声明(明确声明哪些外部变量可以被该Lambda表达式使用)
下面是一个简单的例子,其中 [] 表示不捕获任何外部变量,所以在 lambda 表达式体内,无法访问外部变量。
int a = 123;
auto f = [a] { cout << a << endl; };
f(); // 输出:123
//或通过“函数体”后面的‘()’传入参数
auto x = [](int a){cout << a << endl;}(123);
捕获列表可以是以下几种形式:
[]: 不捕获任何变量。[=]: 一种默认捕获模式,Lambda 体中引用的任何外部变量通过值捕获。[&]: 一种默认捕获模式,Lambda 体中引用的任何外部变量通过引用捕获。[&total, factor]: 显示声明捕获列表,通过引用捕获total,通过值捕获factor。[total, &factor]: 显示声明捕获列表,通过值捕获total,通过引用捕获factor。[&, factor]:facetor用值捕获,其余变量用引用捕获。[=, &total]:total用引用捕获,其余变量用值捕获。
在Lambda表达式中,如果以传值方式捕获外部变量,则函数体中不能修改该外部变量,否则会引发编译错误。而如果使用 mutable 关键字,就可以在表达式体内的代码修改值捕获的变量。
int main()
{
int a = 123;
auto f = [a]()mutable { cout << ++a; }; // 不会报错
cout << a << endl; // 输出:123
f(); // 输出:124
}
与普通函数参数不同,lambda 参数有以下限制。
- 参数列表中不能有默认参数
- 不支持可变参数
- 所有参数必须有参数名