图中的标注如下所示:
-
lambda-introducer(在本主题的后面称为“capture 子句”)
-
lambda declarator(在本主题的后面称为“参数列表”)
-
mutable(在本主题的后面称为“可变规范”)
-
exception-specification(在本主题的后面称为“异常规范”)
-
trailing-return-type(在本主题的后面称为“返回类型”)
-
compound-statement(在本主题的后面称为“lambda 体”)
以下各节对该语法进行了更详细的说明。
Capture 子句
lambda 表达式是类、构造和函数调用运算符。 如同,在定义类时,决定需要发生的对象捕获变量不受值还是引用或者是否是必需的。如果 lambda 表达式需要访问局部变量和函数参数,它们需要 捕获。 get 子句 (语法中的lambda-introducer ) 所指定 lambda 表达式的主体是可以访问在封闭范围内的变量通过值或通过引用:包含" &的变量 (&) 为前缀) 没有& 前缀的引用和变量访问值由访问。
空 capture 子句 [ ] 指示 lambda 表达式的主体不访问封闭范围中的变量。
捕获默认模式指定您未显式指定的获取变量是否捕获通过值或通过引用,如果使用它们。 您可以通过将 & 或= 指定为 capture 子句的第一个元素来指定默认捕获模式(语法中的 capture-default)。 &元素指定 lambda 表达式的主体通过引用访问所有捕获的变量,除非您显式地另行指定。 = 元素指定 lambda 表达式的主体通过值访问所有捕获的变量,除非您显式地另行指定。例如,如果 lambda 表达式的主体通过引用访问外部变量 total 并通过值访问外部变量 factor,那么以下 capture 子句等效:
[&total, factor] {factor, &total] [&, factor] [factor, &] [=, &total] [&total, =]即:[=]表示lambda体中是通过const值传递来引用的外部局部变量,[&]则表示lambda中是通过引用传递来引用的外部局部变量。加上变量的名字就表示显示的指明了该变量是通过const值传递引用还是通过引用传递来引用它。
[&, i]{}; // OK [&, &i]{}; // ERROR: i preceded by & when & is the default [=, this]{}; // ERROR: this when = is the default [i, i]{}; // ERROR: i repeated [=,i]{};//ERROR
举例:
int main()
{
vector<int>m_vec;
for(vector<int>::size_type i = 0;i<8;i++)
{
m_vec.push_back(i);
}
int size = 0;
for_each(m_vec.begin(),m_vec.end(),[&size](int n){
cout<<n;
size ++;
if(n%2 == 0)
{
cout<<"是偶数"<<endl;
}
else
{
cout<<"是奇数"<<endl;
}
});
cout<<"一共有"<<size<<"个数字"<<endl;
return 0;
}
//再来一个例子
#include<functional>
int main()
{
function<int(int,int)>f = [=](int x,int y)->int{return x+y;};
int x = 10,y = 2;
cout<<f(x,y)<<endl;
}
//运行结果 12
既然lambda表达式可以取代函数指针,那么看下例
int main()
{
int x = 10,y = 2;
int result = [=](int value_x,int value_y)->int{return value_x + value_y;}(x,y);//其实就是一个函数调用
cout<<result<<endl;
result = [=]()->int{return x+y;}(); //引用外部的局部变量
cout<<result<<endl;
}