c++ lambda表达式
C++第五版的书上是这么写的:一个lambda表达式表示一个可以调用的代码单元。可以将其理解为一个内联函数。与任何函数类似。一个lambda具有一个返回类型,一个参数列表和函数体。只是类似,并不是完全相同。Lambda可能定义在函数内部。Lambda的具体形式如下:
[capture list](parameter list)->return type{ function body}
capture list通常缺省为空,它是Lambda所在函数定义的局部比变量的列表。lambda表达式必须使用尾置返回。可以忽略参数列表和返回类型,必须有capture list和function body。
例如:
#include <iostream>
using namespace std;
int main()
{auto f = [] //[]捕获列表为空;{ return 1; };//函数体;cout << f() << endl;//调用和普通函数无差别;return 0;
}
向lambda传递参数
调用lambda时给的实参来初始化lambda的形参
- 通常实参和形参的类型必须一致;
- lambda不能有默认参数,实参和形参数目相等。
[](const string &a,const string &b)
{return a.size()>b.size();}
使用捕获列表
lambda以一对[]开始,可以在其中提供一个以逗号分隔的名字列表,这些名字是在函数中定义(这个词准确吗?看下面的例子,没定义sz)的,看起来不需要在捕获列表中定义类型。
[sz](const string &a)
{return a.size() > sz;
}
值捕获
#include <iostream>
using namespace std;
int main()
{size_t v1 = 42;auto f1 = [v1]{ return v1; };v1 = 0;cout << f1() << endl;return 0;
}
输出42
由于被捕获变量的值是在lambda创建时拷贝,因此随后对其修改不会影响到lambda内对应的值。
引用捕获
#include <iostream>
using namespace std;
int main()
{size_t v1 = 42;auto f2 = [&v1]{ return v1; };v1 = 0;cout << f2() << endl;return 0;
}
输出0
v1 之前的&指出 v1 应该以引用方式捕获。一个以引用方式捕获的变量与其他任何类型的引用的行为类似。在lambda函数体内使用此变量时,实际上使用的是引用所绑定的对象。在本例中,当 lambda返回 v1 时,它返回的是 v1 指向的对象的值。采用引用方式捕获一个变量,就必须确保被引用的对象在lambda执行的时候是存在的。lambda捕获的都是局部变量,这些变量在函数结束后就不复存在了。如果lambda可能在函数结束后执行,捕获的引用指向的局部变量已经消失。引用捕获有时是必要的。
lambda
默认情况下,对于一个值被拷贝的变量, lambda不会改变其值。如果我们希望能改变一个被捕获的变量的值,就必须在参数列表首加上关键字mutable。因此,可变lambda能省略参数列表:
#include <iostream>
using namespace std;
int main()
{int v1 = 100;auto f = [v1]() mutable{ return ++v1; };cout << f() << endl;return 0;
}
#include <iostream>
using namespace std;
int main()
{int v1 = 100;auto f = [&v1]{ return ++v1; };cout << f() << endl;return 0;
}
以上两段代码结果一致101。