简介
Lambda表达式是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,Lambda表达式用于封装传递给算法或异步方法的几行代码。
语法定义
捕获列表 mutable throw() -> 返回类型 {函数体}
捕获列表。Lambda函数可以通过捕获列表访问一些上下文的数据。
参数列表。和普通函数的参数列表一致,如果不需要参数传递,可以把()一起省略。
可变规格。默认情况下,Lambda函数总是一个const函数,mutable修饰符可以取消其常量性。在使用mutable时,参数列表不可省略,即使为空。
异常说明。用于Lambda表达式内部函数是否抛出异常。
返回类型。我们可以在不需要返回值的时候连同符号->一起省略。此外,在返回型明确的情况下,也可以省略该部分,让编译器对返回类型进行推导。
Lambda函数体。内容与普通函数一样,不过除了可以使用参数之外,还可以使用所有捕获的变量。
捕获列表参数
- []表示不捕获任何变量;
- [var]表示值传递方式捕获变量var;
- [=]表示值传递方式捕获所有父作用域的变量,包括this。
- [&var]表示引用传递捕获变量var。
- [&]表示引用传递方式捕获所有父作用域的变量,包括this。
- [this]表示值传递方式捕获当前的this指针。
class Lambda
{
public:
void sayHello() {
std::cout << "Hello" << std::endl;
};
void lambda() {
auto function = [this]{
this->sayHello();
};
function();
}
};
- [=,&a,&b]表示以引用传递方式捕获变量a和b,以值传递方式捕获其他所有变量。
- [&,a,this]表示以值传递方式捕获变量a和this,以引用传递方式捕获其他所有变量。
优缺点
在需要调用的地方直接定义短小精悍的函数,而不需要预先定义好函数。
是代码更紧凑,结构层次明显,代码可读性好。
语法灵活,增加了阅读代码的难度。
对代码复用无能为力。
工作原理
编译器会把一个lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator()方法。
auto print = []{cout<<"hello world"<<endl;};
会被翻译为
class print_class
{
public:
void operator()(void) const
{
cout<<"hello world" <<endl;
}
}
auto print = print_class();
C++仿函数
仿函数functor又称函数对象,是一个能行使函数功能的类,重载了operator()运算符。仿函数的原理和Lambda表达式的原理相似。
Lambda表达式使用场景
- 用于STL算法库;
- 短小不需要复用函数场景;
- 多线程场景;
- 函数指针与function;
- 作为函数的入参。