lamda表达式

提示:文章

文章目录

  • 前言
  • 一、背景
      • 在使用lambda的时候,有几个参数是可以直接省略的:
  • 二、题目
      • 问题探究
  • 总结

前言

前期疑问:
本文目标:


lamda表达式

一、背景

看c++科二的时候有看到lamda表达式,就再次看了下

这次稍微有点看懂

lamda表达式结构:

lambda的结构是:[ ] () -> 返回值类型 { }。从左到右依次是:捕捉列表 函数参数 -> 返回值类型 函数体。

解析上述的结构

在使用lambda的时候,有几个参数是可以直接省略的:

​ 1.参数列表可以省略(写() 或者不写())。

​ 2.返回值可以省略(不写 -> 类型)。

​ 除此之外的东西都不可省略(捕捉列表,函数体实现)。

上述变化最多的应该就是捕捉列表。

[ ]不捕捉任何变量
[var]表示值传递方式捕捉变量var显式捕捉
[=]表示值传递方式捕获所有父作用域中的变量(包括this)隐式捕捉
[&var]表示引用传递捕捉变量var;显式捕捉;可以改变变量值
[&]表示引用传递捕捉所有父作用域中的变量(包括this);隐式捕捉;可以改变变量值
[this]捕获当前类中的 this 指针

a. 父作用域指包含lambda函数的语句块
b. 语法上捕捉列表可由多个捕捉项组成,并以逗号分割。
比如:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量 [&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量

auto fun1 = [&](int c) {b = a + c; };
fun1(10);
cout << a << " " << b << endl;

c. 捕捉列表不允许变量重复传递,否则就会导致编译错误。 比如:[=, a]:=已经以值传递方式捕捉了所有变量,捕捉a重复

int x = 10;
auto add_x = [x, =](int a) mutable { x *= 2; return a + x; };
cout << add_x(10) << endl;

d. 在块作用域以外的lambda函数捕捉列表必须为空。
e. 在块作用域中的lambda函数仅能捕捉父作用域中局部变量,捕捉任何非此作用域或者非局部变量都会导致编译报错。
f. lambda表达式之间不能相互赋值,即使看起来类型相同

lambda表达式实际上可以理解为无名函数,该函数无法直接调用,如果想要直接调用,可借助auto将其赋值给一个变量。

参考文档:C++入门——“C++11-lambda”

c++11新特性:lambda表达式

Lambda表达式

二、题目

下面加上喂饭宝典的几个题目。

1、(单选)【lambda】下面代码运行结果是(B)

int n = 1;
auto func1 = [=] { return n; };
auto func2 = [&] { return n; };
n++;
cout<<func1()<<" "<<func2()<<endl;                                                                                                                                         

A. 1 1

B. 1 2

C. 2 2

D. 2 1

解释:Lambda 表达式的 [] 用来确定捕获参数:

[=]:捕获的局部变量只可读不可写,捕获范围是当前 Lambda 表达式之前的作用域。

[&]:捕获的局部变量可读可写。

2、(单选)【lambda】如下程序的输出结果是(D)

#include <functional>using namespace std;auto g1(int x)
{return [&x](int y) { return x + y; };
}auto g2(int& x)
{return [&x](int y) { return x + y; };
}int main()
{int x = 1;auto f1 = g1(x);auto f2 = g2(x);cout<<f1(2)<<,<<f2(2)<<endl;x = 2;cout<<f1(2)<<,<<f2(2)<<endl;return 0;
}

A. 3,3,3,4

B. 3,3,4,4

C. 不确定,3,不确定,3

D. 不确定,3,不确定,4

解释:g1 按引用捕获了局部变量,函数退出局部变量引用就不确定了,所以输出也是不确定的

3、(单选)【lambda】以下代码输出是(B)

void ShowLambda()
{int var = 5;static int base = 3;auto func = [=]() mutable {++base;++var;return base + var;};auto ret1 = func();auto ret2 = func();cout<<ret1<<" "<<ret2<<" "<<var<<" "<<base<<endl;
}int main()
{ShowLambda();return 0;
}

A. 10 12 5 3

B. 10 12 5 5

C. 10 10 5 5

D. 12 12 7 5

解释:

lambda表达式相当于创建了一个struct,把var变成了私有变量。

另外每个lambda表达式即使参数相同,也会新建不同的对象,如auto a = []{}; auto b = []{},a和b所有内部变量不共享,因为它们被视为两个不同的函数

[=]为值传递 int变量会在函数里面进行++操作,函数外面又恢复原值。注意静态变量,与引用传递和值传递无关,

4、(单选)【lambda】以下代码输出是

void ShowLambda(){int var = 5;static int base = 3;auto func = [&]() mutable {++base;++var;return base + var;};base++;var++;auto ret1 = func();auto ret2 = func();std::cout << "ret1 = " << ret1 << ", ret2 = " << ret2 << ",var = " << var << ", base = " << base << std::endl;}

答案:ret1 = 12, ret2 = 14, var = 8, base = 6

解释:【&】地址传递,int变量值也会增加

注意[=] 和 [&]的区别

如果改成func = [=]() mutable

则输出ret1 = 11, ret2 = 13, var = 6, base = 6

问题探究

其中针对第四题,自己写了验证代码

void ShowLambda2()
{int var = 5;static int base = 3;auto func = [&]() mutable {++base;++var;return base + var;};auto ret1 = func();auto ret2 = func();std::cout << "ret1 = " << ret1 << ", ret2 = "<< ret2 << ",var = " << var << ", base = " << base << std::endl;
}//预测10 11 6 5  实际 10 12 7 5,理解就是传引用变量值会被更改并保留void ShowLambda()
{int var = 5;static int base = 3;auto func = [=]() mutable {++base;++var;return base + var;};auto ret1 = func();auto ret2 = func();std::cout << "ret1 = " << ret1 << ", ret2 = "<< ret2 << ",var = " << var << ", base = " << base << std::endl;
}// 预测报错或者10, 11, 5, 5 实际10 12 5,5   理解可能虽然按值传递,但是在同一作用域内,变量会累计自增变化
// ?????这边无法理解为什么ret2为12。。。。void ShowLambda4()
{int var = 5;static int base = 3;auto func = [&]() mutable {++base;++var;return base + var;};std::cout << "var = " << var << ", base = " << base << std::endl;           // 这边打印验证,经过lamda定义语句时不会对变量发生改变base++;var++;auto ret1 = func();auto ret2 = func();std::cout << "ret1 = " << ret1 << ", ret2 = "<< ret2 << ",var = " << var << ", base = " << base << std::endl;
}// 预测 12 14 8 6,实际也为12 14 8 6。理解就是捕捉的val为5,base为3,因为传的是引用,随着自增后val为6,base为4,func函数内部自增后val为7,base为5,和为12。
// 第二次执行func,此时val为7,base为5,因为传引用,此时随着自增后val为8,base为6,所以和为14。void ShowLambda5()
{int var = 5;static int base = 3;auto func = [=]() mutable {++base;++var;return base + var;};std::cout << "var = " << var << ", base = " << base << std::endl;base++;var++;auto ret1 = func();auto ret2 = func();std::cout << "ret1 = " << ret1 << ", ret2 = "<< ret2 << ",var = " << var << ", base = " << base << std::endl;
}// 预测 12 14 8 6  实际 11 ,13, 6 ,6  理解就是虽然base和val在函数定义后面++,但是base和val的值在lamda函数表达式在定义时已经捕捉。所以func执行时,val为5,base虽然一开始被捕捉时是3,但是受自增影响后为4,在函数内部自增后,val为6, base为5,相加ret1为11。
// 第二次执行func,val依然为5,base此时为5,在函数内部都自增后,val为6,base为6,相加为12。

总结

未完待续

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/65234.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

XXL-RPC v1.8.1 | RPC服务框架

Release Notes 1、【安全】序列化安全性增强&#xff0c;默认开启package安全空间机制&#xff1b;2、【扩展】序列化扩展性增强&#xff0c;支持自定义序列化package白名单&#xff1b;3、【优化】序列化类型主动检测&#xff0c;提升问题定位效率&#xff1b;4、【能力】服务…

前端路由layout布局处理以及菜单交互(三)

上篇介绍了前端项目部署以及基本依赖的应用&#xff0c;这次主要对于路由以及布局进行模块化处理 一、 创建layout模块 1、新建src/layout/index.vue <template><el-container class"common-layout"><!-- <el-aside class"aside">&l…

Spring Boot(4)使用 IDEA 搭建 Spring Boot+MyBatis 项目全流程实战

文章目录 一、⚡搞个引言二、⚡开始搭建 Spring Boot 项目吧&#xff01;2.1 启动 IDEA 并创建新项目2.2 选择项目依赖2.3 完成项目创建 三、&#x1f4d8;项目结构剖析四、✍配置数据库连接五、✍ 创建 MyBatis 相关组件5.1 实体类&#xff08;Entity&#xff09;5.2 Mapper 接…

【数据可视化-11】全国大学数据可视化分析

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

141.《mac m1安装mongodb详细教程》

文章目录 下载从官网下载安装包 下载后双击解压出文件夹安装文件名修改为 mongodb配置data存放位置和日志log的存放位置启动方式一方式二方式二:输入mongo报错以及解决办法 本人电脑 m2 pro,属于 arm 架构 下载 官网地址: mongodb官网 怎么查看自己电脑应该下载哪个版本,输入…

frameworks 之 Winscope 工具

frameworks 之 Winscope 工具 1. 手机端开启2. 加载追踪的文件2.1 Android12 3. 分析文件 Winscope 是一款 Web 工具&#xff0c;可以让用户在动画和转换期间和之后记录、重放和分析多个系统服务的状态。Winscope 将所有相关的系统服务状态记录在一个跟踪文件中。使用带有跟踪文…

【姿态估计实战】使用OpenCV和Mediapipe构建锻炼跟踪器【附完整源码与详细说明】

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

cityhash–对字符串的哈希算法

原文地址&#xff1a;cityhash–对字符串的哈希算法 – 无敌牛 欢迎参观我的个人博客&#xff1a;无敌牛 – 技术/著作/典籍/分享等 分享一个给字符串计算hash的开源库&#xff0c;谷歌出品。 源代码在&#xff1a;https://github.com/google/cityhash 可以自己下载&#x…

spring cloud微服务分布式架构

spring cloud微服务分布式架构 应用架构 单体应用架构&#xff1a;all in one 如&#xff1a;前端后端部署在一台服务器中 web应用和数据库放在同一台服务器中&#xff0c;只要服务器挂掉&#xff0c;应用就会终止。 分布式架构&#xff1a;将一个系统拆分为多个独立的组件&…

【HarmonyOS】鸿蒙应用点9图的处理(draw9patch)

【HarmonyOS】鸿蒙应用点9图的处理&#xff08;draw9patch&#xff09; 一、前言&#xff1a; 首先在鸿蒙中是不支持安卓 .9图的图片直接使用。只有类似拉伸的处理方案&#xff0c;鸿蒙提供的Image组件有与点九图相同功能的API设置。 可以通过设置resizable属性来设置Resiza…

深入Android架构(从线程到AIDL)_12 Android UI 单线程程序

目录 6、 Android UI 单线程程序 單線程程序概念 单线程可避免线程安全问题 SurfaceView与非UI线程 6、 Android UI 单线程程序 單線程程序概念 单线程程序意谓着两个(或多个)线程不能共享对象或变量值。Android的UI是单线程程序的环境。UI控件(如Button等)都是由UI线程所…

STM32-笔记36-ADC(模拟/数字转换器)

一、什么是ADC&#xff1f; 全称&#xff1a;Analog-to-Digital Converter&#xff0c;指模拟/数字转换器。 ADC可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量&#xff0c;建立模拟电路到数字电路的桥梁。 12 位 ADC 是一种逐次逼近型模拟数字转换器&#xff08;0…

房产销售系统(源码+数据库+文档)

亲测完美运行带论文&#xff1a;文末获取源码 文章目录 项目简介&#xff08;论文摘要&#xff09;运行视频包含的文件列表&#xff08;含论文&#xff09;前端运行截图后端运行截图 项目简介&#xff08;论文摘要&#xff09; 随着科学技术的飞速发展&#xff0c;各行各业都在…

游戏社交趋势下,游戏语音再升级!

如今&#xff0c;游戏已成为我们社交生活的一个重要娱乐方式&#xff0c;春节临近&#xff0c;与亲朋好友一起畅玩“开黑”无疑是节假日的一大乐趣。在游戏社交互动中&#xff0c;“游戏语音”不可或缺。在传统游戏语音领域&#xff0c;多人在线游戏如 MOBA、FPS 和 MMORPG 的实…

HTML5实现好看的博客网站、通用大作业网页模板源码

HTML5实现好看的博客网站、通用大作业网页模板源码 前言一、设计来源1.1 主界面1.2 列表界面1.3 文章界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的博客网站、通用大作业网页模板源码&#xff0c;博客网站源码&#xff0c;HTML模板源码&#xff0…

ArcGIS中怎么把数据提取到指定范围(裁剪、掩膜提取)

最近&#xff0c;经常能收到怎么把数据提取到指定范围、栅格数据怎么裁剪、矢量数据怎么裁剪、栅格数据怎么掩膜提取的咨询。 下面是我对这个问题的解决思路&#xff1a; 对于矢量数据&#xff1a; ①首先把数据加载进来 ②软件界面上面的工具栏找到→地理处理→裁剪&#x…

node.js内置模块之---stream 模块

stream 模块的作用 在 Node.js 中&#xff0c;stream 模块是一个用于处理流&#xff08;stream&#xff09;的核心模块。流是一种处理数据的抽象方式&#xff0c;允许程序处理大量数据时不会一次性将所有数据加载到内存中&#xff0c;从而提高性能和内存效率。通过流&#xff0…

手持PDA终端,提升零售门店管理效率

随着科技的不断进步和零售行业的持续发展&#xff0c;手持PDA终端的应用将会越来越广泛。它将不断融合更多先进的技术和功能&#xff0c;为零售门店管理带来更加便捷、高效、智能的解决方案。 手持PDA终端是集成了数据处理、条码扫描、无线通信等多种功能于一体的便携式设备‌…

【51单片机-零基础chapter1】

安装软件(配套的有,不多赘述) 1.管理员身份运行keil和破解软件kegen 将CID代码复制粘贴到 一定要管理员方式,不然会error 插入板子 我的电脑,管理 1.如果是拯救者,查看端口,如果没有则显示隐藏 2.苹果不知道,好像不可以 3.其他电脑在"其他设备找" (注:本人在校已…

使用JMeter玩转tidb压测

作者&#xff1a; du拉松 原文来源&#xff1a; https://tidb.net/blog/3f1ada39 一、前言 tidb是mysql协议的&#xff0c;所以在使用过程中使用tidb的相关工具连接即可。因为jmeter是java开发的相关工具&#xff0c;直接使用mysql的jdbc驱动包即可。 二、linux下安装jmet…