为什么要lambda函数
匿名函数是许多编程语言都支持的概念,有函数体,没有函数名。1958年,lisp首先采用匿名函数,匿名函数最常用的是作为回调函数的值。正因为有这样的需求,c++引入了lambda 函数,你可以在你的源码中内联一个lambda函数,这就使得创建快速的,一次性的函数变得简单了。例如,你可以把lambda函数可在参数中传递给std::sort函数。
#include "stdafx.h" #include <algorithm> //标准模板库算法库 #include <cmath> //数学库 #include <iostream> using namespace std; //绝对值排序 void abssort(float* x, unsigned n) { //模板库排序函数 std::sort(x, x + n, // Lambda 开始位置 [](float a, float b) { return (std::abs(a) < std::abs(b)); } // lambda表达式结束 ); } int _tmain(int argc, _TCHAR* argv[]) { float a[5] = { 2.1f, 3.5f, 4.0f, 5.2f, 3.3f }; abssort(a, 5); for (auto& x : a) { cout << x << endl; } system("pause"); return 0; }
lambda函数的语法
基本形式如下:
[capture](parameters)->return-type {body}
- []叫做捕获说明符,表示一个lambda表达式的开始。接下来是参数列表,即这个匿名的lambda函数的参数。
- parameters,普通参数列表
- ->return-type表示返回类型,如果没有返回类型,则可以省略这部分。这涉及到c++11的另一特性,参见自动类型推导,最后就是函数体部分。
- capture clause(捕获)
- lambda-parameter-declaration-list (变量列表)
- mutable-specification (捕获的变量可否修改)
- exception-specification (异常设定)
- lambda-return-type-clause (返回类型)
- compound-statement (函数体)
外部变量的捕获规则
默认情况下,即捕获字段为 [] 时,lambda表达式是不能访问任何外部变量的,即表达式的函数体内无法访问当前作用域下的变量。
如果要设定表达式能够访问外部变量,可以在 [] 内写入 & 或者 = 加上变量名,其中 & 表示按引用访问,= 表示按值访问,变量之间用逗号分隔,比如 [=factor, &total] 表示按值访问变量 factor,而按引用访问 total。
不加变量名时表示设置默认捕获字段,外部变量将按照默认字段获取,后面在书写变量名时不加符号表示按默认字段设置,比如下面三条字段都是同一含义:
[&total, factor]
[&, factor]
[=, &total]
#include <functional> #include <iostream> using namespace std;int _tmain(int argc, _TCHAR* argv[]) { //lambd函数对象 auto fl = [](int x, int y){return x + y; }; cout << fl(2, 3) << endl; function<int(int, int)>f2 = [](int x, int y){return x + y; }; cout << f2(3, 4) << endl; system("pause"); return 0; }
不能访问任何局部变量
如何传进去局部变量
int test = 100; //lambd函数对象捕获局部变量 auto fl = [test](int x, int y){return test +x + y; }; cout << fl(2, 3) << endl;
默认访问所有局部变量
int test = 100; //lambd函数对象捕获所有局部变量 auto fl = [=](int x, int y){return test +x + y; }; cout << fl(2, 3) << endl;