1. 基本概念
Lambda函数,亦称为Lambda表达式、匿名函数等,是一种函数对象,Lambda函数可以让函数像普通变量一样进行赋值、传递、函数返回等操作。C++中的Lambda函数经常用来解决如下问题:
(1)使得程序更加简洁,尤其对于一次性使用的函数。
(2)使得函数可以自由流动,就像变量一样,这给函数式编程模式奠定了语法基础。
2. 语法逻辑
2.1 语义规定
[capture list](params list)mutable exception → return type{functionbody}
解析:
captruelist: 外部变量列表
params list: 形参列表
mutable: 是否可以修改外部变量。
默认情况下,Lambda函数总是一个const函数,mutable可以取消其常量性。
在使用mutable时,形参列表不可省略
exception: 异常设定
return type: 返回类型
可以不需要声明返回值,此时返回类型相当于使用decltyp根据返回值推断得到
function body: 函数体
2.2 基本语法
下面用一些简明的例子,说明如何编写并使用Lambda表达式:
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int a = 1;
int b = 2;
int sum = [a, b]()->int{return a+b;}();
cout << "sum: " << sum << endl;
return 0;
}
在上述代码中,从左到右逐个解释:
Lambda函数是:[a,b]()->int{return a+b;}
a和b是从外部可见作用域中捕获的变量,默认它们在Lambda函数内部是只读的。
()圆括号内是Lambda函数的形参列表,此处为空,但不可省略。
Lambda函数的形参列表一般用于跟容器类结合的时候。
->int 是Lambda函数的返回值类型,可以省略。
{}内部就是Lambda函数的具体代码实现。
请注意,最右边的圆括号 () 是对Lambda函数调用的符号,不是Lamdba函数本身,我们可以将此 Lambda 函数当做一个对象,赋值给另一个具名的函数对象,再去调用它来更清楚地看到Lambda函数的本体:
// 将匿名的Lambda函数,赋值给一个名叫f的函数对象
auto f = [a, b]()->int{return a+b;};
// 两种等价的调用函数对象的形式:
int sum = [a, b]()->int{return a+b;}();
int sum = f();
以引用方式捕获外部参数上述例子捕获的 a 和 b 都是只读的,在Lambda函数内部不可修改,但如果有需要修改这些外部参数,则需要将捕获列表改为引用模式
[&a, b]()->int{a=100; return a+b;}();
上述代码中:&a 代表以引用模式捕获变量a,此时可以在Lambda函数体内修改变量a。
捕获作用域内所有变量。如果作用域内的变量较多,一个个填写到Lambda外部参数列表显然比较麻烦,此时可以用如下代码来一次性全部导入:
// 以传值模式(只读)捕获所有外部变量
[=]()->int{...};
// 以引用模式(读写)捕获所有外部变量
[&]()->int{...};
给Lambda函数传参
就像普通函数一样,可以给Lambda函数传参,比如:
```c++
#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
int a = 1;
int b = 2;
// 定义一个具有两个int形参的Lambda函数
// 并将Lambda函数赋值给函数对象sum(相当于起了个名字以便于后续显式调用)
auto sum =[](int x,int y){return x+y;};
// 调用函数对象
cout << sum(a, b) << endl;
return 0;
}
请注意,上述代码仅仅是为了讲解Lambda函数的形参列表的语法逻辑,而并不是Lambda函数的一般典型用法,因为上述例子已经违背了匿名函数的初衷 —— 将Lambda函数赋值给了一个具名函数对象sum,这么做毫无意义,如果非要定义一个具名函数的话,那么完全可以直接编写一个普通的函数 sum 来达到此功能。
上述代码之所以这么写的原因是,是需要举一个例子来说明Lambda函数的形参的传递过程,而在没有涉及STL容器及其配套算法库函数之前,我们没有用过能被自动调用的函数,因此我们需要一个语句来显式地调用函数,因此就需要一个具名的函数对象sum来承接Lambda函数的功能。
那么,Lambda函数形参列表的典型场景是怎样的呢?这里可以举STL算法库中的最简单的一例加以说明,如果需要对STL容器及其算法库有进一步的了解,请查阅相关课件。
#include <array>
#include <algorithm>
using namespace std;
int main(int argc, char const *argv[])
{
// 定义一个静态数组arr(这是一种STL容器,简单理解为一维数组即可)
array<int, 5> arr = {1,2,3,4,5};
// 使用算法库函数 count_if() 计算 arr 中的偶数数目
int num = count_if(arr.begin(), arr.end(), [](int m){return m%2==0;});
cout << "偶数数目是: " << num << endl;
return 0;
}
标签:return,函数,形参,int,理解,变量,Lambda
From: https://www.cnblogs.com/hhail08/p/18455004