首页 > 其他分享 >Lambda函数的理解

Lambda函数的理解

时间:2024-10-09 19:46:27浏览次数:8  
标签:return 函数 形参 int 理解 变量 Lambda

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

相关文章

  • 关于C++中的异常概念理解
    1.基本概念异常,即exception,是C++中的基本概念之一,在某段程序发生无法继续正常执行的情况时,C++允许程序进行所谓抛出异常(有时也被称为吐出异常)的行为,这些被抛出的异常,会自动地从触发点开始向外传播,直到被捕获(有时也被称为吞下异常)或者程序终止。2.语法2.1抛出异常下面用一......
  • 4.Python 函数(函数的定义、函数的传入参数、函数的返回值、None 类型、函数说明文档、
    一、函数快速入门1、函数概述函数是组织好的,可重复使用的,用来实现特定功能的代码段name="HelloWorld"name_length=len(name)print(f"{name}的长度为{name_length}")#HelloWorld的长度为11len()是Python内置的函数,是提前写好的,可以重复使用,实现统计长......
  • python3常用内置函数及常用库functools使用
    常用内置函数#lambda函数-----------------------------add=lambdaa,b,c:a+b+cprint(add(1,2,3))#6#sorted函数-----------------------------a_l=[1,3,5,7,0,-1,-9,-4,-5,8]print(sorted(a_l))#[-9,-5,-4,-1,0,1,3,5,7,8]p......
  • Hive(六)JSON函数
    概念什么是JSONJSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式,易于人阅读和编写,同时也易于机器解析和生成JSON是存储和交换文本信息的语法,类似XMLJSON比XML更小、更快,更易解析JSON语法数据在名称/值对中数据由,分开使用斜杠\来转义字符大括号{}保存对象......
  • Hive(五)常用函数
    Hive常用函数字符串函数返回值函数描述stringconcat(string/binaryA,string/binaryB…)对二进制字节码或字符串按次序进行拼接intinstr(stringstr,stringsubstr)查找字符串str中子字符串substr出现的位置intlength(stringA)返回字符串的长度int......
  • C语言—函数递归
    目录一.递归的概念①递归的思想②递归的限制条件二.递归的一些典型例子①求n的阶乘②顺序打印一个整数的每一位③斐波那契数列三.递归与迭代一.递归的概念①递归的思想所谓递归,就是把一个大型复杂问题不断转化成一个个规模较小的子问题从而求解,直到子问题不能被......
  • 深入理解HDFS 错误恢复
    我们从动态的角度来看hdfs先从场景出发,我们知道hdfs的写文件的流程是这样的:数据以pipeline的方式写入hdfs,然后对于读取操作,客户端选择其中一个保存块副本的DataNode来读数据.考虑这样两个场景:hbasers在写wallog的时候.如果一个rs挂了.那么这个rs会转......
  • tanh激活函数
    公式tanh⁡(x)=sinh⁡(x)cosh⁡(x)=ex−e−xex+e−x图像:tanh函数的输出范围是(-1,1),这意味着无论输入是什么,输出都会被压缩到这个区间内。主要的点是非线性和助于解决梯度爆炸......
  • PTA JAVA语言 面向对象程序设计 作业二 6-3 Person类 构造Person类。包括姓名(name),性
    6-3Person类 谢谢大佬关注,不定期分享学习笔记,希望大佬能多多支持,三连必回单位 山东科技大学构造Person类。包括姓名(name),性别(sex)和年龄(age)。提供所有属性的set和get函数,提供print函数打印其信息输入描述:姓名(name),性别(sex)和年龄(age)输出描述:用户信息裁判测......
  • [快速阅读八] HDR->LDR:Matlab中tonemapfarbman函数的解析和自我实现。
    最近受朋友的委托,想自己实现Matlab里的一个HDR转LDR的函数,函数名是tonemapfarbman,乘着十一假期,稍微浏览下这个函数,并做了一点C++的实现和优化。为了看到这个函数的效果,需要至少matlab R2018b及其以上的版本。 首先,我们下载了matlab帮助文档中提到的该算法对应的论......