Lambda表达式
-
完整结构
[capture list] (params list) mutable exception -> return type { function body }
-
有时可以省略部分结构,但中括号绝对不能省
int main() { [] { cout << "func()" << endl; }; // 这就是一个lambda表达式,但运行不会打印func()因为这只是个定义,并没有调用 getchar(); return 0; }
int main() { ([] { cout << "func()" << endl; })(); // 这样就调用了,运行后会打印"func()" getchar(); return 0; }
如何存储呢?
-
lambda表达式本质是个函数,应该使用一个指向函数的指针来存储它,取决于右边的函数的返回值是什么。
int main() { void (*p)() = [] { cout << "func()" << endl; }; // 没有返回值所以是void,也可以用auto,反正能自动识别类型 // 调用 p(); getchar(); return 0; }
稍微复杂一点,实现两个数的相加
// [capture list] (params list) mutable exception -> return type { function body } auto p = [](int a, int b) -> int { return a + b; }; cout << p(10, 20) << endl;
-
-
可以作为函数直接传入
int exec (int v1, int v2, int(*func)(int, int)) { return func(v1, v2); } int main() { cout << exec(v1, v2, [] (int v1, int v2) { return v1 + v2; }) << endl; }
-
前面的中括号 -> 变量捕获(值捕获)
int main() { int a = 10; int b = 20; auto func = [] { cout << a << endl; cout << b << endl; } // 直接访问a和b是不行的,应该在方括号内加入值捕获 [a, b] // 表示外面的a和b要拷贝到lambda表达式内 auto func = [a, b] { cout << a << endl; cout << b << endl; } auto func = [=] { // 等号表示隐式捕获(值捕获) cout << a << endl; cout << b << endl; } }
-
注意!值捕获和地址捕获
int main() { int a = 10; auto func = [a] { cout << a << endl; }; a = 20; func(); // 输出为10 getchar(); return 0; }
默认捕获为值捕获,在捕获的时候a = 10,相当于直接把10传进去。
那如果想要做到捕获最新的a值怎么办?
那应该就改成地址捕获
int main() { int a = 10; // 地址捕获 auto func = [&a] { cout << a << endl; }; auto func = [&] { // &表示隐式捕获(地址捕获) cout << a << endl; cout << b << endl; } a = 20; func(); // 输出为20 getchar(); return 0; }
-
-
mutable
int main() { int a = 10; // 如果在lambda里面要改变外面变量的值,应该用地址捕获 auto func = [&a] { a ++; }; func(); // 用mutable // 就算没有参数也要加小括号(格式要求) // 并不会改变a的值,因为没有地址捕获 auto func = [a]() mutable { // 相当于在里面又定义了一个int a = 10; // int a = a ++; cout << "lambda =" << a << endl; // lambda = 11; }; cout << a << endl; // 10; getchar(); return 0; }