匿名函数的基本语法

代码语言:C++

自动换行

AI代码解释


[捕获列表](参数列表) mutable(可选) 异常属性 -> 返回类型 { // 函数体 }

语法规则:lambda表达式可以看成是一般函数的函数名被略去,返回值使用了一个 -> 的形式表示。唯一与普通函数不同的是增加了“捕获列表”。

展开

代码语言:C++

自动换行

AI代码解释


// lambda_test lambda_test.cc #include <iostream> using namespace std; void test01() { cout << "test01" << endl; auto Add = [](int a, int b) -> int { return a + b; }; cout << Add(1, 2) << endl; } int main(int argc,char **argv) { test01(); return 0; }

编译(要指定-std=c++11):

代码语言:Bash

自动换行

AI代码解释


g++ -o lambda_test lambda_test.cc -std=c++11

输出结果:

代码语言:Bash

自动换行

AI代码解释


$ ./lambda_test test01 3

一般情况下,编译器可以自动推断出lambda表达式的返回类型,所以我们可以不指定返回类型,即:

展开

代码语言:C++

自动换行

AI代码解释


// lambda_test lambda_test.cc #include <iostream> using namespace std; void test02() { cout << "test02" << endl; auto Add = [](int a, int b){ return a + b; }; cout << Add(1, 2) << endl; } int main(int argc,char **argv) { //test01(); test02(); return 0; }

但是如果函数体内有多个return语句时,编译器无法自动推断出返回类型,此时必须指定返回类型。

二、捕获列表

有时候,需要在匿名函数内使用外部变量,所以用捕获列表来传递参数。根据传递参数的行为,捕获列表可分为以下几种:

2.1、值捕获

与参数传值类似,值捕获的前提是变量可以拷贝,不同之处则在于,被捕获的变量在 lambda表达式被创建时拷贝,而不是在调用时才拷贝:

展开

代码语言:C++

自动换行

AI代码解释


// lambda_test lambda_test.cc #include <iostream> using namespace std; void test03() { cout << "test03" << endl; int c = 20; int d = 30; auto Add = [c,d](int a, int b) { cout << "d = "<< d << endl; return c; }; d = 10; // 在这里修改 d 的值,会改变 Add里的 d 值吗? cout << Add(1, 2) << endl; } int main(int argc,char **argv) { //test01(); //test02(); test03(); return 0; }

执行结果:

代码语言:Bash

自动换行

AI代码解释


$ ./lambda_test test03 d = 30 20

2.2、引用捕获

与引用传参类似,引用捕获保存的是引用,值会发生变化。

展开

代码语言:C++

自动换行

AI代码解释


#include <iostream> using namespace std; void test04() { cout << "test04" << endl; int c = 20; int d = 30; auto Add = [c, &d](int a, int b) { cout << "c = " << c << endl; cout << "d = " << d << endl; return c; }; d = 10;//在这里修改d的值,会改变Add里的d值吗? cout << Add(1, 2) << endl; } int main(int argc,char **argv) { //test01(); //test02(); //test03(); test04(); return 0; }

执行结果:

代码语言:Bash

自动换行

AI代码解释


$ ./lambda_test test04 c = 20 d = 10 20

2.3、隐式捕获

手动书写捕获列表有时候是非常复杂的,这种机械性的工作可以交给编译器来处理,这时候可以在捕获列表中写一个 & 或 = 向编译器声明采用引用捕获或者值捕获。编译器会将外部变量全部捕获。

更多推荐