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 接…

使用wujie搭建微前端应用及踩坑

线上演示地址&#xff1a;wujie-app 源码地址&#xff1a;https://github.com/Jiang-K-J/micro-app?tabreadme-ov-file &#xff08;如果觉您得有用&#xff0c;请帮忙点个小星星&#xff09; 主应用&#xff1a;vue2webpack 子应用&#xff1a;vue3vite 子应用&#xff1…

【数据可视化-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 将所有相关的系统服务状态记录在一个跟踪文件中。使用带有跟踪文…

在日期字段中自动插入斜杠“/”的最佳方法是什么

我正在尝试向输入日期字段添加功能&#xff0c;以便当用户输入数字时&#xff0c;自动添加斜杠“/”。 所以假设我有以下 html&#xff1a; <input type"text" id"fooDate" />假设我有以下 javascript&#xff1a; var dateField document.getElem…

极限学习机 (Extreme Learning Machine, ELM) 算法详解与PyTorch实现

极限学习机 (Extreme Learning Machine, ELM) 算法详解与PyTorch实现 目录 极限学习机 (Extreme Learning Machine, ELM) 算法详解与PyTorch实现1. 极限学习机 (ELM) 算法概述1.1 单隐层前馈神经网络1.2 ELM的优势2. ELM的核心技术2.1 模型定义2.2 随机初始化2.3 最小二乘法2.4…

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

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

nvm如何安装

一、简介 在实际的开发和学习中可能会遇到不同项目的 node 版本不同&#xff0c;而出现的兼容性问题。 而 nvm 就可以很好的解决这个问题&#xff0c;它可以在同一台机器上下管理多个 node 版本&#xff0c;使得程序员可以轻松地安装、卸载和切换不同的 node 版本。 在下载和配…

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…