c++11中引入Lambda表达式,便于定义和创建匿名函数。
完整表达式:
[capture list] (parameters) mutable ->returntype {function body}
参数含义:
1、capture list:捕获到的外部变量列表(函数体可直接使用的外部变量)
2、parameter:形参列表、类似于函数中的形参
3、mutable:若有,则可修改值捕获的外部变量
4、returntype:返回类型
lamdba表达式为匿名函数,即没有名字的函数。上述中,参数名、函数体、返回类型与普通函数一致,多了捕获列表与mutable。
此外,捕获形式主要可分为值捕获/传递和引用捕获/传递,体现在捕获列表,[&a]引用捕获,[a]值捕获,后文将详细介绍,此处简单说明。
省略后的lambda表达式:
1、[capture list] (parameters) ->returntype {function body}
省略了mutable,表明若捕获列表中为值捕获,则不可更改捕获变量;若为引用捕获, 加不加mutable不影响变量的修改。
2、[capture list] (parameters) {function body}
进一步省略了返回值类型,此时,有无返回值以及返回值类型由函数体决定。
3、[capture list] {function body}
更进一步省略了形参列表,相当于普通函数中无形参传入的情形。注:若有mutable, 则必须有形参,即使括号里为空。
捕获变量的几种形式:
1、值捕获,相当于值传递,不会改变捕获变量的内容。
int main()
{
int a = 10;
auto f1 = [a]() { cout << a << endl;};
cout << a << endl; // 输出为 10
a = 20;
f1(); // 输出为 10,传入a时,等价于auto f1 = [10](){}
cout << a << endl; // 输出为20,
return 0;
}
2、引用捕获:类似于引用传递,会改变捕获变量的内容
int main()
{
int a = 10;
auto f1 = [&a]() { cout << a << endl;};
cout << a << endl; // 输出为10
a = 20; // 输出为20,传入的是a的地址,a=20改变时,相应内容变
f1();
cout << a << endl; // 输出为20
return 0;
}
3、隐式捕获:不指定变量,编译器根据函数体所需变量进行捕获。隐式捕获也分为两种方式,即[=]值捕获,[&]引用捕获
int main()
{
int a = 10;
auto f1 = [=]() { cout << a << endl;};
cout << a << endl; // 输出为 10
a = 20;
f1(); // 输出为 10,类似于值捕获
cout << a << endl; // 输出为20,
return 0;
}
int main()
{
int a = 10;
auto f1 = [&]() { cout << a << endl;};
cout << a << endl; // 输出为10
a = 20; // 输出为20,类似于引用捕获
f1();
cout << a << endl; // 输出为20
return 0;
}
4、混合形式的捕获
[]:不捕获外部变量
[变量名, …] :捕获若干变量,默认为值捕获,若需引用捕获,则需加&
[this]:值捕获this指针
[=, &x]:引用捕获x变量,值捕获其余变量
[&, x]:值捕获x变量,引用捕获其余变量
括号中的参数:
上文说到括号中的参数与普通函数中的形参类似,但仍存在一下差别
1、参数列表不可有默认参数。(注:自己在编译器中,好像加默认参数也能运行)
2、不支持可变参数。int printf( const char* format, ...);三个点即为可变参数
3、所有参数均需有参数名
mutable:
上文中可知,在值捕获中,不可修改变量的值。若想要修改变量值,则可利用mutable。
int main()
{
int a = 10;
auto f1 = [=]() mutable { cout << ++a << endl;};
cout << a << endl; // 输出为10
a = 20;
f1(); // 输出为11,利用了mutable,则先++a,再输出
cout << a << endl; // 输出为20
return 0;
}
int main()
{
int a = 10;
auto f1 = [&]() mutable { cout << ++a << endl;};
cout << a << endl; // 输出为10
a = 20;
f1(); // 输出为21,利用了mutable,且为引用,故传入的为20
cout << a << endl; // 输出为21,lambda中进行了a值得自加
return 0;
}
参考自://www.cnblogs.com/DswCnblog/p/5629165.html