C++11的lambda运算
lambda是希腊字母表中的第十一位。lambda演算是计算机语言领域的老古董,它是20实际30年代Alonzo Church推演出来的为了证明计算机机的可计算性的产物。
在C++11中lambda函数语法定义如下:
[capture] (parameters) mutable -> return-type{statement};
其中:
- [capture]:捕捉列表。用来捕捉上下文中的变量以供lambda函数使用,事实上,[]是lambda的引出符,编译器根据该引出符判断接下来的代码是否是lambda函数
- (parameters):参数列表。与普通函数参数列表一致,如果不需要参数传递,则可以连同括号一同省略
- mutable: 修饰符。默认情况下lambda函数总是一个const函数,mutable可以取消其常量性,但使用该修饰符时,参数列表不可省略(即使参数为空)
- ->return-type: 返回类型。用于追踪返回类型形式函数的返回类型。当不需要返回类型时也可以连同->一起省略。此外在返回类型明确的情况下,也可以省略该部分,让编译器对返回类型进行类型推导。
1。 捕捉列表可以由多个捕捉项组成,并以逗号分隔。
- [var] 表示值传递方式捕捉变量var
- [&var] 表示按引用传递捕捉变量var
- [=] 表示按值传递方式捕捉所有父作用域的变量,包括this
- [&] 表示按引用传递方式捕捉所有父作用域的变量,包括this
- [this] 表示按值传递方式捕捉当前的this指针
[] {} // 最简短的lambda函数
int a=3, b = 4;
[=]{return a+b;} // 省略了参数和返回类型,并按值使用a,b
auto add = [a, &b]()->int{return a+b;};
2。 使用lambda函数时,捕捉列表不同会导致不同的效果。对于按值方式传递的捕捉列表,其传递值在lambda函数定义的时候就已经绑定好了;对于按引用传递的捕捉列表变量,其传递的值则等于lambda函数调用时的值。
int j = 12;
auto by_val = [=]{return j + 1;};
auto by_ref = [&]{return j + 1;};
std::cout << "by val: " << by_val() << std::endl; // 13
std::cout << "by ref: " << by_ref() << std::endl; // 13
j++;
std::cout << "by val: " << by_val() << std::endl; // 13
std::cout << "by ref: " << by_ref() << std::endl; // 14