Lambda表达式介绍
Lambda表达式是一种描述函数对象的机制,它的主要应用是描述某些具有简单行为的函数,Lambda表达式也可以称为匿名函数。
Lambda常见的表达式如下:
方式一:[ captures ] ( params ) -> ret { body }
方式二:[ captures ] ( params ) { body }
方式三:[ captures ] { body }
表达式参数说明:
[ captures ]表示捕获列表,具体捕获方式规则如下:
[&] 以引用捕获所有用于 lambda 体内的自动变量,并以引用捕获当前对象,若存在
[=] 以复制捕获所有用于 lambda 体内的自动变量,并以引用捕获当前对象,若存在
[] 不捕获
[=, &i] 除了 i 以引用捕获,其余的 都以复制方式捕获
[&, i] 除了 i 以复制捕获,其余的 都以引用方式捕获
[a,&b] 其中 a 以复制捕获而 b 以引用捕获
[this] 以引用捕获当前对象( *this )
(params)表示函数参数
params 可以有零个或者一个以上的参数
-> ret 表示返回值
ret表示返回类型,可以是int,int*等;
若缺失,则由函数的 return 语句所隐含(或若函数不返回任何值则为 void )
{ body }表示函数体
捕获范围
Lambda表达式在变量或者对象的作用域范围内都可以进行捕获,包括局部变量、全局变量等;不再作用域范围内的变量无法捕获,例如:
不能捕获的情况
int main()
{
{
//变量x,y的作用域仅限制在这括号中,离开这里即无效
int x = 10;
int y = 10;
}
//编译告警
[&x,&y](){ x += 1; y+=1;}();
std::cout << x << ' ' <<y;
return 0;
}
[&x,&y](){ x += 1; y+=1;}();
编译有误,提示信息如下:
error: 'x' was not declared in this scope
error: 'y' was not declared in this scope
去掉变量x,y所在的花括号,其作用域在main函数中都可见,函数运行结果如下:
11 11
捕获方式介绍
捕获方式可以有复制捕获和引用捕获两种,在一个捕获块中这两种捕获方式可以混合使用,进行非法操作,编译错误。
int main()
{
int x = 10;
int y = 10;
//Lambda表达式,ok
[&x, &y]()
{
x++;
y++;
}();
//Lambda表达式,error
/*
[x, &y]()
{
x++; //复制捕获,不能++;
y++;
}();
*/
//运行结果:x: 10 y: 11
std::cout << "x: " << x << " y: " << y << std::endl;
return 0;
}
Lambda表达式和泛型算法的应用
Lambda表达式和算法结合后,简化编码情况,具体应用如下:
可以参考 仿函数应用比较两种差异
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
int main()
{
std::vector<int> v = {50, -10, 20, -30};
// 排序时按照默认规则
//此时v中的数据应该是 { -30, -10, 20, 50 }
std::sort(v.begin(), v.end());
// 利用Lambda表达式,按照绝对值排序
std::sort(v.begin(), v.end(),
[](int a, int b)
{
return abs(a) < abs(b) ;
});
//print result
for(auto var: v)
{
//运行结果:-10 20 -30 50
std::cout << var <<"\t";
}
return 0;
}