lambda表达式是为了解决人们在编程时为了实现一个algorithm算法而重新写一个类的情况
int main()
{
int array[] = {4,1,8,5,3,7,0,9,2,6};
// 默认按照小于比较,排出来结果是升序
std::sort(array, array+sizeof(array)/sizeof(array[0]));
// 如果需要降序,需要改变元素的比较规则
std::sort(array, array + sizeof(array) / sizeof(array[0]), greater<int>());
return 0;
}
如果是内置类型那么还可以使用库中的函数,但是若是自定义类型那么就需要我们自己去定义排序时的比较规则
struct Goods
{
string _name;
double _price;
};
struct Compare
{
bool operator()(const Goods& gl, const Goods& gr)
{
return gl._price <= gr._price;
}
};
int main()
{
Goods gds[] = { { "苹果", 2.1 }, { "相交", 3 }, { "橙子", 2.2 }, {"菠萝", 1.5} };
sort(gds, gds+sizeof(gds) / sizeof(gds[0]), Compare());
return 0;
}
如果每次比较的逻辑不一样,就要实现多个类,这无疑带来了极大的不便,而使用lambda表达式就可以解决这个问题
int main()
{
Goods gds[] = { { "苹果", 2.1 }, { "相交", 3 }, { "橙子", 2.2 }, {"菠萝", 1.5} };
sort(gds,gds + sizeof(gds) / sizeof(gds[0]), [](const Goods& l, const Goods& r)
->bool
{
return l._price < r._price;
});
return 0;
}
上述代码就是用lambda表达式来解决的,可以看出lambda表达式就是一个匿名函数
lambda表达式语法
[ ] ( )mutable ->returntype { };
[捕捉列表] :出现在lambda的开始位置,编译器根据[ ]来判断接下来的代码是否为lambda函数,捕获列表可以捕捉上下文中的变量供lambda函数使用
(参数列表):参数列表,普通函数列表一样,可以省略
mutable:因为lambda表达式是一个const函数,mutable可以取消它的常量性,使用这个修饰符时参数列表不能省略
->returntype: 返回值类型,用追踪返回类型形式声明返回值类型,返回值类型明确情况下可以省略由编译器进行类型推演
{函数体}:函数体
捕捉列表中参数:
- [ var ] 表示值传递方式捕捉变量var
- [ = ] 表示值传递的方式捕捉所有父作用域中的变量(包括this)
- [ &var ] 表示引用的方式捕捉变量var
- [ & ] 表示引用的方式捕捉所有父作用域中的的变量
- [ this ] 表示值传递的方式捕捉当前的this指针
注意:
a.
父作用域指包含
lambda
函数的语句块
b.
语法上捕捉列表可由多个捕捉项组成,并以逗号分割
。
比如:
[=, &a, &b]
:以引用传递的方式捕捉变量
a
和
b
,值传递方式捕捉其他所有变量
[&
,
a, this]
:值
传递方式捕捉变量
a
和
this
,引用方式捕捉其他变量
c.
捕捉列表不允许变量重复传递,否则就会导致编
译错误
。 比如:
[=, a]
:
=
已经以值传递方式捕捉了所有变量,捕捉
a
重复
d.
在块作用域以外的
lambda
函数捕捉列表必须为空
。
e.
在块作用域中的
lambda
函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都
会导致编译报错。
f.
lambda
表达式之间不能相互赋值
,即使看起来类型相同