C++11之lambda表达式初探
2018-04-11 本文已影响25人
小pb
C++11 中的lambda表达式,用于顶一个并创建一个匿名的函数对下,以简化编程工作。
一. 语法
[ capture-list ] ( params ) mutable exception attribute -> ret { body }
[函数对象参数] (操作符重载函数参数) mutable或exception声明 ->返回值类型 {函数体}
1、函数对象参数
函数对象参数,是标识一个lambda表达式的开始,这部分必须存在,不能省略。函数对象参数是传递给编译器自动生成的函数对象类的构造函数。换句话说,Lambda函数可以引用在它之外声明的变量. 这些变量会在方括号[]内. 成为一个闭包。下面是一些常用的例子。
[] // 未定义变量.试图在Lambda内使用任何外部变量都是错误的.
[x, &y] // x 按值捕获, y 按引用捕获.
[&] // 用到的任何外部变量都隐式按引用捕获(包括Lambda所在类的this)
[=] // 用到的任何外部变量都隐式按值捕获(包括Lambda所在类的this)
[&, x] // x显式地按值捕获. 其它变量按引用捕获
[=, &z] // z按引用捕获. 其它变量按值捕获
-
操作符重载函数参数
标识重载的()操作符的参数,没有参数时,这部分可以省略。参数可以通过按值(如:(a,b))和按引用(如:(&a,&b))两种方式进行传递。
这就是一个函数声明:[&a](int v){ cout << v+a << endl; }
注意这里函数的声明和函数的调用要区分开。
-
mutable或exception声明
这部分可以省略。按值传递函数对象参数时,加上mutable修饰符后,可以修改按值传递进来的拷贝(注意是能修改拷贝,而不是值本身)。exception声明用于指定函数抛出的异常,如抛出整数类型的异常,可以使用throw(int)。
// 以引用方式传递作用域内所有可见的局部变量(包括this),输出:11 13 12 { int a = 10; for_each(vctTemp.begin(), vctTemp.end(), [&](int v)mutable{ cout << v+a << endl; a++; }); cout << a << endl; } // 以值方式传递局部变量a,输出:11 13 10 { int a = 10; //注意:在lambda表达式中的 a 只是一个拷贝,添加mutable之后,可以修改a的值,但只是修改拷贝的a for_each(vctTemp.begin(), vctTemp.end(), [a](int v)mutable{ cout << v+a << endl; a++; }); cout << a << endl; }
-
->返回值类型,
标识函数返回值的类型,当返回值为void,或者函数体中只有一处return的地方(此时编译器可以自动推断出返回值类型)时,这部分可以省略。 -
函数体,标识函数的实现,用{}括起来的,这部分不能省略,但函数体可以为空,这部分和c++正常的函数体一样。
这里给出一个完整的写法:
[](int x, int y) -> int { int z = x + y; return z; }
End