C++ 匿名函数详解及使用方法
1、匿名函数的使用
匿名函数的基本语法为:
//[捕获列表](参数列表)->返回类型(函数体)
in main()
{
auto Add = [](int a, int b) -> int {
return a + b;
}
std::cout << Add(1, 2) << std::endl;
return 0;
}
上述代码输出结果:3
。
注意点:一般情况下,编译器可以自动推断出 Lambda 表达式的返回类型,所以我们可以不指定返回类型,即:
//[捕获列表](参数列表){函数体}
int main()
{
auto Add = [](int a, int b) {
return a + b;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
但是如果函数体内有多个 return
语句时,编译器无法自动推断出返回类型,此时必须指定返回类型。
2、匿名函数的使用
试图在 Lambda 内使用外部变量是错误的,例如:
#include <iostream>
using namespace std;
int main()
{
int c = 12;
auto Add = [](int a, int b) -> int {
return c;
};
cout << Add(1, 2) << endl;
return 0;
}
但是有些时候我们需要使用外部变量,所以需要使用捕获列表,上述代码改写成以下形式便可以通过编译。
#include <iostream>
using namespace std;
int main()
{
int c = 12;
auto Add = [c](int a, int b) -> int {
return c;
};
cout << Add(1, 2) << endl;
return 0;
}
但是如果你更改一下 Lambda 表达式中代码块的内容,比如在上述代码中添加一句
c = a;
这样又会无法编译通过了,因为你的 c
是按值传递的,所以要将捕获列表改成
[&c](int a, int b)->int{...};
这样 c
的值便是按引用传递了,便可以进行修改。
补充知识:
-
如果捕获列表为
[&]
,则表示所有的外部变量都按引用传递给 Lambda 使用 -
如果捕获列表为
[=]
,则表示所有的外部变量都按值传递给 Lambda 使用 -
匿名函数构建的时候对于按值传递的捕获列表,会立即将当前可以取到的值拷贝一份作为常数,然后将该常数作为参数传递,即:
int main()
{
int c = 12;
auto Add = [c](int a, int b) -> int { // Add构建的时候实际是:[12](int a,int b)->int{}
return c;
};
std::cout << Add(1, 2) << std::endl;
return 0;
}
到此,匿名函数(Lambda 表达式)的基础使用方法就介绍完毕了。
3、Lambda 表达式简介
3.1、介绍 Lambda
一个 Lambda 表达式表示一个可调用的代码单元,我们可以将它理解为一个未命名的内联函数。和任何函数类似,一个 Lambda 表达式具有一个返回类型,一个参数列表和一个函数体,但和普通函数不一样的是 Lambda 表达式可能定义在函数内部。我们可以忽略 Lambda 表达式的参数列表和返回类型,但不可以忽略捕获列表和函数体。
//
//这是正确的(忽略了参数列表和返回类型)
//
//为什么没有指定返回类型还可以返回整数值?
//因为你的函数体有return语句,它可以推断出来
auto f = []{ return 1 + 2; };
3.2、Lambda 捕获列表
[] | 空捕获列表,Lambda 不能使用所在函数中的变量 |
[names] | names 是一个逗号分隔的名字列表,这些名字都是 Lambda 所在函数的局部变量。默认情况下,这些变量会被拷贝,然后按值传递,名字前面如果使用了 & ,则按引用传递 |
[&] | 隐式捕获列表,Lambda 体内使用的局部变量都按引用方式传递 |
[=] | 隐式捕获列表,Lambda 体内使用的局部变量都按值传递 |
[&,identifier_list] | identifier_list 是一个逗号分隔的列表,包含 0 个或多个来自所在函数的变量,这些变量采用值捕获的方式,其他变量则被隐式捕获,采用引用方式传递,identifier_list 中的名字前面不能使用 & 。 |
[=,identifier_list] | identifier_list 中的变量采用引用方式捕获,而被隐式捕获的变量都采用按值传递的方式捕获。identifier_list 中的名字不能包含 this ,且这些名字面前必须使用 & 。 |
转载自:风雅yaya
感谢
%%%
woc终于知道怎么写了