内容学习自:爱编程的大丙
1.前言
- 声明式编程:不需要写额外的命名函数和函数对象
- 简洁,使得开发高效
- 实现功能打包,使程序灵活
lambda定义了一个匿名函数,并且可以捕捉一定范围内的变量,用法:
//[capture](params) opt -> ret {body;};
//例
void main()
{
int a = 10,b = 20;
auto c = [&] {return a++;}
auto d = [=,&b] {return a + (b++);}
}
代表意思依次是:capture捕获列表,params参数列表,opt函数选项,ret返回值类型,body函数体。
2.捕获列表:
- [] - 不捕捉任何变量
- [&] - 捕获外部作用域中所有变量,并作为引用在函数体内使用 (按引用捕获)
- [=] - 捕获外部作用域中所有变量,并作为副本在函数体内使用 (按值捕获),注意副本在表达式内部为只读
- [=, &foo] - 按值捕获外部作用域中所有变量,并按照引用捕获外部变量 foo
- [bar] - 按值捕获 bar 变量,同时不捕获其他变量
- [&bar] - 按引用捕获 bar 变量,同时不捕获其他变量
- [this] - 捕获当前类中的 this 指针 -让表达式拥有类成员同样的访问权限 -如果已经使用了&或者=,默认添加此选项
注意如果要对外部变量进行修改,就要通过引用的方式捕获。
3.返回值
一般情况下,不指定 lambda 表达式的返回值,编译器会根据 return 语句自动推导返回值的类型,但需要注意的是 labmda表达式不能通过列表初始化自动推导出返回值类型,另外,返回值可以省略。
// 完整的lambda表达式定义
auto f = [](int a) -> int
{
return a+10;
};
// 忽略返回值的lambda表达式定义
auto f = [](int a)
{
return a+10;
};
4.mutable
对按值传递的数值修改其只读属性
int a = 1;
auto f1 = [=]{return a++;};//error
auto f2 = [=]()mutable {return a++;};//ok
5.lamdba本质,以及使用
lamdba本质是一个仿函数,可以使用std::function和std::bind来储存和操作
void main()
{
//包装
std::function<int(int)> func1 = [](int a){return a;};
//绑定
std::function<int(int)> func2 = bind([](int a){return a;},placeholders::_1);
cout<<func1(1)<<endl;
cout<<func2(2)<<endl;
}
此外没有捕获外部变量的lamdba表达式还可以变成普通函数指针
using fptr = int(*)(int);
fptr f = [](int a)
{
return a;
{
int a = f(3);
cout << a;