当前位置: 首页 > news >正文

Lambda表达式

什么是 Lambda表达式

Lambda表达式是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象(闭包)的简便方法。Lambda表达式的基本语法如下:

//[capture list] (parameter list) -> return type { function body }
auto func = []() -> int { return 42; };

这里的“-> int”是后置返回类型,指定了 Lambda 表达式的返回类型为 int。
 

在c++的官方文档中,给出了lamda表达式的四种写法,所以在官方文档上截了一个图。

其中:

capture list 是捕获列表,用于指定 Lambda表达式可以访问的外部变量,以及是按值还是按引用的方式访问。捕获列表可以为空,表示不访问任何外部变量,也可以使用默认捕获模式 & 或 = 来表示按引用或按值捕获所有外部变量,还可以混合使用具体的变量名和默认捕获模式来指定不同的捕获方式。
parameter list 是参数列表,用于表示 Lambda表达式的参数,可以为空,表示没有参数,也可以和普通函数一样指定参数的类型和名称,还可以在 c++14 中使用 auto 关键字来实现泛型参数。
return type 是返回值类型,用于指定 Lambda表达式的返回值类型,可以省略,表示由编译器根据函数体推导,也可以使用 -> 符号显式指定,还可以在 c++14 中使用 auto 关键字来实现泛型返回值。
function body 是函数体,用于表示 Lambda表达式的具体逻辑,可以是一条语句,也可以是多条语句,还可以在 c++14 中使用 constexpr 来实现编译期计算。

捕获方式说明
[]不捕获任何变量。
[&]捕获外部作用域中的所有变量,并作为引用在函数体中使用(按引用捕获)。
[=]捕获外部作用域中的所有变量,并作为副本在函数体中使用(按值捕获)。
[=,&foo]按值捕获外部作用域中的所有变量,并按引用捕获 foo 变量。
[a, &b]以值的方式捕获 a,以引用的方式捕获 b,也可以捕获多个。
[bar]按值捕获 bar 变量,同时不捕获其他变量。
[this]捕获当前类中的 this 指针,让 Lambda 表达式拥有和当前类成员函数同样的访问权限。如果已经使用了 & 或者 =,就默认添加此选项。捕获 this 的目的是可以在 Lambda 中使用当前类的成员函数和成员变量。

Lambda表达式的捕获方式

值捕获(capture by value):在捕获列表中使用变量名,表示将该变量的值拷贝到 Lambda 表达式中,作为一个数据成员。值捕获的变量在 Lambda 表达式定义时就已经确定,不会随着外部变量的变化而变化。值捕获的变量默认不能在 Lambda 表达式中修改,除非使用 mutable 关键字。例如:

int x = 10;
auto f = [&x] (int y) -> int { return x + y; }; // 引用捕获 x
x = 20; // 修改外部的 x
cout << f(5) << endl; // 输出 25,受外部 x 的影响

引用捕获(capture by reference):在捕获列表中使用 & 加变量名,表示将该变量的引用传递到 Lambda 表达式中,作为一个数据成员。引用捕获的变量在 Lambda 表达式调用时才确定,会随着外部变量的变化而变化。引用捕获的变量可以在 Lambda 表达式中修改,但要注意生命周期的问题,避免悬空引用的出现。例如:

int x = 10;
auto f = [x] (int y) -> int { return x + y; }; // 值捕获 x
x = 20; // 修改外部的 x
cout << f(5) << endl; // 输出 15,不受外部 x 的影响

隐式捕获(implicit capture):在捕获列表中使用 = 或 &,表示按值或按引用捕获 Lambda 表达式中使用的所有外部变量。这种方式可以简化捕获列表的书写,避免过长或遗漏。隐式捕获可以和显式捕获混合使用,但不能和同类型的显式捕获一起使用。例如:

int x = 10;
int y = 20;
auto f = [=, &y] (int z) -> int { return x + y + z; }; // 隐式按值捕获 x,显式按引用捕获 y
x = 30; // 修改外部的 x
y = 40; // 修改外部的 y
cout << f(5) << endl; // 输出 55,不受外部 x 的影响,受外部 y 的影响

初始化捕获(init capture):C++14 引入的一种新的捕获方式,它允许在捕获列表中使用初始化表达式,从而在捕获列表中创建并初始化一个新的变量,而不是捕获一个已存在的变量。这种方式可以使用 auto 关键字来推导类型,也可以显式指定类型。这种方式可以用来捕获只移动的变量,或者捕获 this 指针的值。例如:

int x = 10;
auto f = [z = x + 5] (int y) -> int { return z + y; }; // 初始化捕获 z,相当于值捕获 x + 5
x = 20; // 修改外部的 x
cout << f(5) << endl; // 输出 20,不受外部 x 的影响

Lambda表达式的优点
Lambda表达式相比于普通函数和普通类,有以下几个优点:

简洁:Lambda表达式可以省略函数名和类名,直接定义和使用,使得代码更加简洁和清晰。
灵活:Lambda表达式可以捕获外部变量,可以作为函数参数,也可以作为函数返回值,使得代码更加灵活和方便。
安全:Lambda表达式可以控制外部变量的访问方式,可以避免全局变量的定义,可以避免悬空指针和无效引用的产生,使得代码更加安全和稳定。

总结
Lambda表达式是 c++11 引入的一个语法,它可以用来定义并创建匿名的函数对象,主要用于方便编程,避免全局变量的定义,并且变量安全。Lambda表达式的语法类似于一个函数定义,但它不需要函数名,可以直接定义并使用。Lambda表达式相比于普通函数和普通类,有以下几个优点:简洁、灵活和安全。Lambda表达式本质上是一个匿名类的对象,因此它可以赋值给一个函数指针或函数引用,也可以作为模板参数传递给一个泛型函数或类。C++14 和 C++17 对 Lambda表达式进行了一些扩展和改进,使得 Lambda表达式更加强大和灵活,主要有以下几个方面:泛型 Lambda、初始化捕获和捕获 this 指针。

http://www.dtcms.com/a/466822.html

相关文章:

  • SD12C.TCT瞬态电压抑制(TVS)二极管Semtech升特 电子元器件IC解析
  • wordpress后台添加导航珠海网络排名优化
  • nftables 是什么
  • 基于AD9361的天气雷达回波模拟与硬件系统(三)
  • Fast AutoAugment
  • wordpress 主题 小众百度整站优化
  • Linux内核驱动-Linux系统移植
  • Python人脸检测
  • 鱼骨建站公司专业高端网站设计首选
  • 大模型前世今生(十一):信息论——信息准确传输的上限
  • 马云做中国最大的网站产品开发管理系统
  • 教程网站后台密码石家庄市网站制作价格
  • day94—树—平衡二叉树判断(LeetCode-110)
  • 前端页面渲染方式梳理
  • Linux命令之ping用法
  • 怎么自己做五合一网站旅游短租公寓网站建设
  • 飞凌嵌入式ElfBoard-Linux系统基础入门-网络相关shell命令
  • [VoiceRAG] RTMiddleTier实时中间层 | WebSocket处理器 | 拦截
  • 美图秀秀“AI合照”功能风靡欧洲,荣登14国应用商店总榜第一
  • Arduino实战:智能家居控制系统的设计与实现
  • 网站seo评测常州中环做网站多少钱
  • 电影网站建设教程江苏常州建设局网站
  • 格式化json文件
  • PostgreSQL `pg_trgm` 性能调优与索引维护
  • 怎么找个人搭建网站网站h5什么意思
  • 基于单片机的多功能面粉面条馒头面点制作机设计
  • CMP平台(类Cloudera CDP7.3)在华为鲲鹏的Aarch64信创环境中的性能表现
  • HarmonyOS鸿蒙 - 获取设备唯一标识
  • 网站10月份可以做哪些有意思的专题天津网络优化招聘
  • [crackme]026-KeygenMe