lambda 表达式定义了一个匿名函数,并且可以捕获一定范围内的变量。
定义:
[ capture list] ( parameters) mutable throw() -> return-type { statement; };
capture list:捕获列表
parameters:参数列表
mutable throw():异常说明
return-type:返回值类型
statement:函数体
-------------------------------------------------------------------------------------------------------------------------
可省略为:
[ capture list] ( parameters) -> return-type { statement; };
[ capture list] ( parameters){ statement; };
[ capture list] { statement; };
捕获变量
1.[]为空时,表示不捕获变量
auto p = [] { std::cout << "Hello World!" << std::endl; }; p();
2.[var]表示以值传递的方式捕获变量var
int num = 100; auto p = [num] { std::cout << num << std::endl; }; p();
3.[=]表示以值传递方式捕获父作用域(上级作用域)的所有变量
int num = 100; int a = 20; auto p = [=] { std::cout << num << a << std::endl; }; p();
4.[&var]表示以引用的方式捕获变量var
int num = 100; auto p = [&num] { num = 200; std::cout << num << std::endl; }; p();
5.[&]表示以引用的方式捕获父作用域的所有变量
6.[=, &var]表示出了var以引用的方式捕获,其他的全是以值传递的方式捕获
7.[this]表示捕获当前的this指针
class Person { private: int m_age; public: void sayHello() { std::cout << "Hello" << std::endl; } void lamada() { auto p = [this] { this->sayHello(); }; p(); } };
参数列表
同函数的参数列表类似
mutable修饰符
lamada表达式是const函数,所以值传递的数据再函数体都不能改值,而mutable就是用来去除const的修饰的。此时()就不能省略了。
int num = 100; int a = 20; [a, &num] () mutable { num = 200; a = 30; std::cout << num << std::endl; std::cout << a << std::endl; }(); std::cout << a << std::endl;
值得注意的是,外面的a并没有影响,因为是值传递
throw异常
[]() throw() { throw "Wrong"; };
工作原理
编译器会把一个lambda表达式生成一个匿名类的匿名对象,并在类中重载函数调用运算符,实现了一个operator() const方法。