基本语法
lambda表达式可以看作是一般的函数的函数名被略去,返回值通过->的形式表示。唯一与普通函数不同的地方是增加了“捕获列表”.
[捕获列表](参数列表) mutable(可选) 异常属性 -> 返回值类型 { 函数体 } auto Add = [](int a, int b) -> int { return a+b; }; |
一般情况下,编译器可自动推断出返回值类型,因此我们可以不人为指定。如果有多个return语句,则需要人为指定返回类型。
捕获列表
有时,需要在匿名函数内使用外部变量,所以使用捕获列表来获取传递参数。
空捕获
即捕获列表为空,代表Lambda中不可以使用所在函数中的变量
值捕获
对比于函数传值,传的是值。值捕获的前提是变量可以拷贝。并且,在lambda内部,不可以直接修改捕获的值
被捕获的变量在lambda表达式创建时拷贝,而非调用时才拷贝。也就意味着,如果在lambda函数创建和调用的中间,人为改变了捕获的值,并不会改变lambda函数内部的值。
void test3() { cout << "test3" << endl; int c = 12; int d = 30; auto Add = [c, d](int a, int b)->int { cout << "d = " << d << endl; return c; }; d = 20; std::cout << Add(1, 2) << std::endl; //d的输出为30而非20 } |
引用捕获
传的是引用,lambda表达式会修改传入的值
auto Add = [&c, &d](int a, int b)-> int{ cout<< "d = " << d << endl; return c; } |
引用捕获的变量是在lambda表达式调用时,变量是多少,就是多少
隐式捕获
[&] : 表示lambda中可以调用外部的所有变量,且都是引用捕获
【=】: 表示lambda可以调用外部的所有变量,且均为值捕获
表达式捕获
可以捕获右值。允许捕获的成员用任意的表达式初始化,被声明的捕获变量类型会自动判断
void test9() { cout << "test9" << endl; auto important = std::make_unique<int>(1); auto add = [v1 = 1, v2 = std::move(important)](int x, int y) -> int { return x + y + v1 + (*v2); }; std::cout << add(3,4) << std::endl; } |
泛型lambda
C++14以后,lambda的形式参数可以使用auto关键字来产生意义上的泛型。也就是声明为auto
//泛型 Lambda C++14 void test10() { cout << "test10" << endl; auto add = [](auto x, auto y) { return x+y; }; std::cout << add(1, 2) << std::endl; std::cout << add(1.1, 1.2) << std::endl; } |
可变lambda
采用值捕获的方式,如果想要在函数内部修改它的值(这个不会影响全局),可以用mutable修饰.
采用引用捕获的方式,lambda可以直接修改其值
void test12() { cout << "test12" << endl; int v = 5; // 值捕获方式,使用mutable修饰,可以改变捕获的变量值 auto ff = [v]() mutable {return ++v;}; v = 0; auto j = ff(); // j为6 } void test13() { cout << "test13" << endl; int v = 5; // 采用引用捕获方式,可以直接修改变量值 auto ff = [&v] {return ++v;}; v = 0; auto j = ff(); // v引用已修改,j为1 } |