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

C++11--lambda表达式

目录

lambda表达式的概念

lambda表达式语法

lambda表达式的书写格式

捕捉列表

参数列表

mutable

返回值类型

函数体

lambda表达式交换两个数

函数对象与lambda表达式


lambda表达式的概念

        lambda表达式是一个匿名函数 它能让代码更加地简洁 提高了代码可读性

首先定义一个商品类

struct Goods
{string _name;      // 名字double _price;     // 价格int _evaluate;     // 评价Goods(const char* str, double price, int evaluate):_name(str), _price(price), _evaluate(evaluate){}
};

假设我们要对这些商品进行排序

  • 如果要对于一个数据集合中的元素进行排序 我们可以使用sort函数 但是因为这里待排序的是一个结构体 所以我们要自行定义一个比较规则
  • 要控制sort函数的比较方式有两种方式:一种是重载商品类的()运算符,一种是仿函数
  • 但是由于这里需要比较的方式不是唯一的 所以不能重载()运算符 只能使用仿函数

下面是几种仿函数

struct ComparePriceLess
{bool operator()(const Goods& g1, const Goods& g2){return g1._price < g2._price;}
};struct ComparePriceGreater
{bool operator()(const Goods& g1, const Goods& g2){return g1._price > g2._price;}
};struct CompareNumLess
{bool operator()(const Goods& g1, const Goods& g2){return g1._num < g2._num;}
};struct CompareNumGreater
{bool operator()(const Goods& g1, const Goods& g2){return g1._num > g2._num;}
};

之后我们如果要使用sort函数直接使用仿函数的匿名对象就可以

vector<Goods> v = { { "苹果", 2.1, 300 }, { "香蕉", 3.3, 100 }, { "橙子", 2.2, 1000 }, { "菠萝", 1.5, 1 } };sort(v.begin(), v.end(), ComparePriceLess()); // 按价格升序排序   这里的ComparePriceLess()其实是一种匿名对象
sort(v.begin(), v.end(), ComparePriceGreater()); //按价格降序排序
sort(v.begin(), v.end(), CompareNumLess());      //按数量升序排序
sort(v.begin(), v.end(), CompareNumGreater());   //按数量降序排序

虽然仿函数确实能够解决这里的问题 但是它具有以下问题

  1. 在一般的类中成员变量都是私有的 如果我们想使用仿函数进行成员变量之间的比较要声明友元函数
  2. 仿函数的命名要是不具有可读性我们就很难理解是按照什么比较的

关于第二点问题的解决 我们这里提出一种新的解决方案 lambda表达式

lambda表达式语法

lambda表达式的书写格式

[capture-list](parameters)mutable->return-type{statement}

上面的代码可以修改成:

int main()
{vector<Goods> v = { { "苹果", 2.1, 5 }, { "香蕉", 3, 4 }, { "橙子", 2.2, 3 }, { "菠萝", 1.5, 4 } };//auto priceLess = [](const Goods& g1, const Goods& g2){return g1._price < g2._price; };//sort(v.begin(), v.end(), priceLess);sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price < g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._price > g2._price; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate < g2._evaluate; });sort(v.begin(), v.end(), [](const Goods& g1, const Goods& g2){return g1._evaluate > g2._evaluate; });
}

捕捉列表

 [capture-list]

        该列表总是出现在lambda函数的最前面 它的作用跟main函数类似 编译器根据它的位置来判断下面的代码是否为lamdba函数 捕捉列表能够捕捉上下文中的变量供lambda函数使用

参数列表

(parameters)

        与普通函数的参数列表使用方式一致 如果没有参数需要传递可以连同小括号一起省略

mutable

mutable

        默认情况下 lambda函数总是一个const函数 mutable可以取消其常属性 使用该修饰符时 参数列表不可省略(即使参数为空)

返回值类型

->return-type
  •    用追踪返回类型形式声明函数的返回值类型 没有返回值时此部分可以省略
  •    返回值类型明确情况下也可省略 由编译器对返回类型进行推导

函数体

{statement}

函数体内就是要写函数的主体 除了可以使用其参数外 还可以使用所有捕获到的变量

lambda函数的参数列表和返回值类型都是可选部分 但捕捉列表和函数体是不可省略的 因此最简单的lambda函数如下:

int main()
{[]{};             //最简单的lambda表达式return 0;
}

捕获列表说明

捕获列表描述了上下文中哪些数据可以被lambda函数使用 以及使用的方式是传值还是传引用

  • [var]:表示值传递方式捕捉变量var
  • [=]:表示值传递方式捕获所有父作用域中的变量(成员函数包括this指针)
  • [&var]:表示引用传递捕捉变量var
  • [&]:表示引用传递捕捉所有父作用域中的变量(成员函数包括this指针)
  • [this]:表示值传递方式捕捉当前的this指针

这里对于捕捉列表的一些名词概念予以说明

  • 父作用域指的是包含lambda函数的语句块
  • 语法上捕捉列表可由多个捕捉项组成 并以逗号分割 比如[=, &a, &b]
  • 捕捉列表不允许变量重复传递 否则会导致编译错误 比如[=, a]重复传递了变量a
  • 在块作用域以外的lambda函数捕捉列表必须为空 即全局lambda函数的捕捉列表必须为空
  • 在块作用域中的lambda函数仅能捕捉父作用域中的局部变量 捕捉任何非此作用域或者非局部变量都会导致编译报错
  • lambda表达式之间不能相互赋值 即使看起来类型相同

lambda表达式交换两个数

传统写法

int a = 10;
int b = 20;auto swap = [](int& x, int& y)->void{int z = x;x = y;y = z;
};swap(a, b);
  • 因为lambda表达式是一种匿名函数 所以无法直接调用 如果想要调用 我们可以借助auto关键字将其赋值给一个变量 用该变量来实现功能
  • lambda表达式的函数体最后还有一个分号

捕获列表的使用

以引用的方式捕捉所有父作用域中的变量 省略参数列表和返回值类型 

int a = 10;
int b = 20;auto swap = [&a, &b] // (使用& 捕获所有参数 也可以)
{int z = a;a = b;b = z;
};swap(); // 我们这里还必须要调用以下这个函数才会使用

传值捕捉

我们的lambda函数默认是具有常属性的 它不会修改内部对象的值

所以要先使用mutable关键字省略其常属性 但是省略了这个属性之后参数列表就不能省略

int a = 10;
int b = 20;auto swap = [=]()mutable{int z = a;a = b;b = z;
};swap(); 

但是传值传递本质上是对于原始数据的一份临时拷贝 它的修改并不会改变原始的数据 所以调用了swap函数也不会发生变化

在全局中不能捕捉对象

int a = 0, b = 1;
//在全局中不能捕捉对象
//auto func5 = [a, b](){};
auto func5 = [](){};

如果用了就会报错

 

函数对象与lambda表达式

函数对象,又称为仿函数,即可以像函数一样使用的对象,就是在类中重载了operator()运算符的
类对象。
class Rate
{
public:Rate(double rate): _rate(rate){}double operator()(double money, int year){ return money * _rate * year;}private:double _rate;
};int main()
{// 函数对象double rate = 1.34;Rate r1(rate);r1(10000, 2);// lambdaauto r2 = [=](double monty, int year)->double{return monty*rate*year; };r2(10000, 2);return 0;
}
从使用方式上来看,函数对象与lambda表达式完全一样
函数对象将rate作为其成员变量,在定义对象时给出初始值即可,lambda表达式通过捕获列表可
以直接将该变量捕获到
实际在底层编译器对于lambda表达式的处理方式,完全就是按照函数对象的方式处理的,即:如
果定义了一个lambda表达式,编译器会自动生成一个类,在该类中重载了operator()
底层原理,其实是被处理成一个lambda_uuid的一个仿函数类

相关文章:

C++11--lambda表达式

目录 lambda表达式的概念 lambda表达式语法 lambda表达式的书写格式 捕捉列表 参数列表 mutable 返回值类型 函数体 lambda表达式交换两个数 函数对象与lambda表达式 lambda表达式的概念 lambda表达式是一个匿名函数 它能让代码更加地简洁 提高了代码可读性 首先定义…...

四【Spring框架】

目录一 Spring概述二 .Spring 的体系结构三 Spring的开发环境3.1 配置pom.xml文件四 项目案例&#xff1a;4.1 创建实体类4.2 在pom.xml中引入依赖4.3 配置Spring-config.xml文件4.4 Test✅作者简介&#xff1a;Java-小白后端开发者 &#x1f96d;公认外号&#xff1a;球场上的…...

树与二叉树 总复习

一、树的定义 树是一个有n个&#xff08;n>0&#xff09;结点的有限集合。 如果n0&#xff0c;称为空树&#xff1b; 如果n>0&#xff0c;称为非空树&#xff0c;有且仅有一个特定的称为根Root的结点&#xff08;无直接前驱&#xff09; 如果n>1,除了根节点外&…...

window10安装MySQL数据库

准备好软件MySql的下载参考&#xff1a;(1137条消息) mysql下载与安装过程_weixin_40396510的博客-CSDN博客_mysql数据库下载安装(1137条消息) 安装MySQL的常见问题_二木成林的博客-CSDN博客_sc不是内部或外部命令,也不是可运行的程序解压要C盘&#xff08;自定义&#xff0c;本…...

羊了个羊游戏开发教程3:卡牌拾取和消除

本文首发于微信公众号&#xff1a; 小蚂蚁教你做游戏。欢迎关注领取更多学习做游戏的原创教程资料&#xff0c;每天学点儿游戏开发知识。嗨&#xff01;大家好&#xff0c;我是小蚂蚁。终于要写第三篇教程了&#xff0c;中间拖的时间有点儿长&#xff0c;以至于我的好几位学员等…...

SHA1详解

目录 一、介绍 二、与MD5的区别 1、对强行攻击的安全性 2、对密码分析的安全性 3、速度 三、应用 1、文件指纹 2、Git中标识对象 四、算法原理 1、填充消息 2、消息处理 3、数据运算 &#xff08;1&#xff09;链接变量 &#xff08;2&#xff09;步函数 一、介绍…...

Go并发介绍及其使用

1. goroutine Go语言通过go关键字来启动一个goroutine。注意&#xff1a;go关键字后面必须跟一个函数&#xff0c;不能是语句或者其他东西&#xff0c;函数的返回值被忽略。 goroutine有如下特性&#xff1a; go的执行是非阻塞的&#xff0c;不会等待。go后面的函数的返回值…...

小米手机屏幕解锁技巧精选

手机锁是一种保护存储的用户数据和信息的方法。存储在锁定手机中的所有信息比任何人都可以访问的手机安全得多。但有时&#xff0c;如果用户忘记了这些屏幕锁定&#xff0c;可能会造成麻烦。在此博客中&#xff0c;我们将帮助用户了解如何解锁小米手机。 什么时候需要解锁小米手…...

「SDOI2009」HH去散步

HH去散步 题目限制 内存限制&#xff1a;125.00MB时间限制&#xff1a;1.00s标准输入标准输出 题目知识点 动态规划 dpdpdp矩阵 矩阵乘法矩阵加速矩阵快速幂 思维 构造 题目来源 「SDOI2009」HH去散步 题目 题目背景 HH 有个一成不变的习惯&#xff0c;喜欢在饭后散步…...

用上Visual Studio后,我的世界游戏的构建时间减少了一半

今天我们讲述一个使用 Visual Studio 提升工作效率的案例。 我的世界(Minecraft) 游戏开发商 Mojang Studios 近日联系了 Visual Studio C 团队&#xff0c;因为他们需要将 C 开发扩展到新平台&#xff08;Linux&#xff09;&#xff0c;同时还希望保留他们现有的技术基础&…...

34、基于51单片机锂电池电压电流容量检测仪表LCD液晶显示 原理图PCB程序设计

方案选择 单片机的选择 方案一&#xff1a;AT89C52是美国ATMEL公司生产的低电压&#xff0c;高性能CMOS型8位单片机&#xff0c;器件采用ATMEL公司的高密度、非易失性存储技术生产&#xff0c;兼容标准MCS-51指令系统&#xff0c;片内置通用8位中央处理器(CPU)和Flash存储单元…...

【Java基础】泛型(一)-基础使用

本文以Java的官方文档为参考&#xff0c;辅以代码示例&#xff0c;尽可能详尽的叙述泛型的每一个特性 什么是泛型 泛型&#xff08;Generics&#xff09;也称为参数化类型&#xff08;parameterized types&#xff09;&#xff0c;也就是将类型本身作为接口、类、方法中的参数…...

学Python不会不知道NumPy计算包吧,带你五分钟看懂NumPy计算包

从今天我们就开始进入 Python 数据分析工具的教程。 前段时间数据分析和Python都讲了一点点&#xff0c;但是Python的数据库&#xff0c;讲的少了点&#xff0c;所以接下来就讲讲这些重要的常用数据库吧&#xff01;&#xff01;&#xff01; Python 数据分析绝对绕不过的四个…...

积水内涝监测——埋入式积水终端设备介绍

一、设备概述 埋入式积水终端是针对城市内涝推出的积水信息监测采集设备&#xff0c;采用超声波传感技术&#xff0c;对积水的深度进行精确的测量。产品能够在低温、腐蚀环境下可靠运行本产品特别适用于智慧城市中&#xff0c;对城市道路、社区低洼处的积水进行实时监测上报到…...

Kafka的日志同步

首先介绍下LEO和HW LEO&#xff1a; 即LogEndOffset&#xff0c;表示该副本下次日志记录的偏移量HW&#xff1a;即HighWatermark&#xff0c;高水位线&#xff0c;是所有ISR副本集合中的LEO最小值上图中&#xff0c;如果此时三个副本都在ISR集合中&#xff0c;那么此时他们的LE…...

【Mybatis源码解析】mapper实例化及执行流程源码分析

文章目录简介环境搭建源码解析基础环境&#xff1a;JDK17、SpringBoot3.0、mysql5.7 储备知识&#xff1a;《【Spring6源码・AOP】AOP源码解析》、《JDBC详细全解》 简介 基于SpringBoot的Mybatis源码解析&#xff1a; 1.如何对mapper实例化bean 在加载BeanDefinition时&a…...

分布式文件管理系统(MinIO)

1.去中心化&#xff0c;每个点是对等的关系&#xff0c;通过Ngix对负载做均衡工作。 好处&#xff1a; 能够避免单点故障&#xff0c;将多块硬盘组成一个对象存储服务。 2. 使用纠删编码技术来保护数据&#xff0c;是一种回复丢失和损坏的数据的数学算法&#xff0c;他将数据分…...

Springcloud-配置中心config

一、添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-config-server</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId&…...

[项目篇] 音乐播放器开发报告

文章目录1. 项目描述:2. 项目上线展现&#xff1a;3. 项目具体实现&#xff1a;1. 登录2. 注册3.退出系统4.添加音乐4.1前后端交互约定4.2上传文件业务逻辑&#xff1a;4.3创建model包中的music类4.4在MusicMapper接口中&#xff0c;声明insertMusic抽象方法4.5在mybatis包中添…...

Spring Cloud Alibaba--gateway微服务详解之网关(二)

1、网关介绍 上篇对微服务中的nacos注册中心进行集成讲解。nacos主要作用是管理多服务之间复杂关系的组件。微服务是非常庞大且问题突出的架构&#xff0c;HTTP协议具有跨源资源共享 (CORS) Cross- Origin Resource Sharing机制&#xff0c;而处于安全考虑往往前端架构都会对跨…...

Zynq非VDMA方案实现视频3帧缓存输出,无需SDK配置,提供工程源码和技术支持

目录1、前言2、VDMA的不便之处3、FDMA取代VDMA实现视频缓存输出4、Vivado工程详解5、上板调试验证并演示6、福利&#xff1a;工程代码的获取1、前言 对于Zynq和Microblaze的用户而言&#xff0c;要想实现图像缓存输出&#xff0c;多半要使用Xilinx推荐的VDMA方案&#xff0c;该…...

血液透析过滤芯气密性检测装置中的高精度多段压力控制解决方案

摘要&#xff1a;针对目前血液过滤芯气密性检测过程中存在的自动化水平较低、多个检测压力之间需人工切换和压力控制精度较差的问题&#xff0c;为满足客户对高精度和自动化气密性检测的要求&#xff0c;本文提出了相应的解决方案。解决方案的主要特点是全过程的可编程压力控制…...

PDF加密如何批量解除?快来了解下这个方法

在现代办公环境中&#xff0c;PDF文档的使用非常普遍。然而&#xff0c;由于一些安全需求&#xff0c;有时候PDF文档会被加密&#xff0c;使得只有授权人员可以查看或修改它。但是&#xff0c;如果您需要对许多加密PDF文档进行操作&#xff0c;逐个解密这些文档可能非常费时费力…...

C++——哈希4|布隆过滤器

目录 布隆过滤器 完整代码 布隆过滤器应用 布隆过滤器的查找 布隆过滤器删除 布隆过滤器优点 布隆过滤器缺陷 布隆过滤器海量数据处理 布隆过滤器 位图只能映射整形&#xff0c;而对于字符串却无能为力。 把字符串用哈希算法转成整形&#xff0c;映射一个位置进行标…...

python冒号的用法总结

一维数组 1. 单个冒号的情况 1.1 写完整的情况下 单个冒号的情况下&#xff0c;对数组的遍历操作是从前向后操作。如&#xff1a;arr[a:b] &#xff0c;冒号前的a含义是从a开始遍历&#xff0c;冒号后的b含义是到b截止&#xff08;不包括b&#xff09;。 arr [1, 2, 3, 4,…...

面试题整理

面试题整理 一、Java基础 1、Java 语言有哪些特点 简单易学&#xff1b; 面向对象&#xff08;封装&#xff0c;继承&#xff0c;多态&#xff09;&#xff1b; 平台无关性&#xff08; Java 虚拟机实现平台无关性&#xff09;&#xff1b; 支持多线程&#xff08; C 语言…...

C语言深度解剖-关键字(7)

目录 switch case 语句 理解&#xff1a; 补充&#xff1a; 深入理解&#xff1a; default 语句&#xff1a; case语句&#xff1a; 总结&#xff1a; do、while、for 关键字 while for do while 各种死循环方法&#xff1a; while for do while getchar 写在…...

利用JavaScript编写Python内置函数查询工具

最近我开始学习Python编程语言&#xff0c;我发现Python拥有非常丰富的内置函数&#xff0c;可以用来实现各种不同的功能。但是每当我需要查找一个内置函数时&#xff0c;我总是需要联网使用搜索引擎进行查询。这种方式不仅费时费力&#xff0c;而且需要联网&#xff0c;很不方…...

【MySQL进阶】SQL优化

&#x1f60a;&#x1f60a;作者简介&#x1f60a;&#x1f60a; &#xff1a; 大家好&#xff0c;我是南瓜籽&#xff0c;一个在校大二学生&#xff0c;我将会持续分享Java相关知识。 &#x1f389;&#x1f389;个人主页&#x1f389;&#x1f389; &#xff1a; 南瓜籽的主页…...

最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境

0 说明 本文基于最新版海豚调度dolphinscheduler-3.1.3配置windows本地开发环境&#xff0c;并在windows本地进行调试和开发 1 准备 1.1 安装mysql 可以指定为windows本地mysql&#xff0c;也可以指定为其他环境mysql&#xff0c;若指定为其他环境mysql则可跳过此步。 我这…...

做网站分期付款比例/google搜索优化

续前&#xff1a;QRCode二维码生成方案及其在带LOGO型二维码中的应用&#xff08;1&#xff09; http://blog.csdn.net/johnsuna/article/details/8525038 首先我们来看看二维码的符号字符区域&#xff0c;然后再看看其编码流程。 QRCode的结构&#xff1a;图9 QRCode的结构 …...

建设部一体化监管平台网站首页/网络营销师培训费用是多少

原文地址&#xff1a;http://www.zhangxinxu.com/wordpress/?p739 一、哗啦哗啦的简介 zxx://这里“哗啦哗啦”的作用是为了渲染一种氛围。content属性早在CSS2.1的时候就被引入了&#xff0c;可以使用:before以及:after伪元素生成内容。此特性目前已被大部分的浏览器支持&…...

wordpress limit login attempts/线上营销方式

之前在项目中使用滑块开关按钮&#xff0c;纯css写的&#xff0c;不考虑兼容低版本浏览器&#xff0c;先说下原理&#xff1a;使用 checkbox 的 选中 checked 属性改变css 伪类样式&#xff0c; 一定要使用-webkit-appearance: none; 先清除checkbox的默认样式 &#xff0c;否则…...

湖北建设监理协会网站/58同城安居客

转自&#xff1a;http://blog.163.com/fghok_018/blog/static/122599670201072773924530/ 近一个月&#xff0c;宿舍的好多同学都买了笔记本电脑&#xff0c;当然&#xff0c;我也买了&#xff0c;学校的网说实话不稳定&#xff0c;貌似局域网游戏也没办法玩&#xff0c;主要是…...

丹阳网站制作/营销的概念是什么

addEventListener 定义和用法 addEventListener 用于向指定元素添加事件句柄&#xff08;又称事件处理函数&#xff09; 语法 element.addEventListener(event, function, useCapture) element 文档节点&#xff0c;duocument&#xff0c;window。 event 必须有。是一个…...

丰台网站建设/淘宝定向推广

UV′(UV)′−U′VUV(UV)-UVUV′(UV)′−U′V ∫UV′dxUV−∫U′Vdx\int UV dx UV - \int UV dx ∫UV′dxUV−∫U′Vdx −−−−−−−−−−−−−−−−−−−−−−−−−−-------------------------- −−−−−−−−−−−−−−−−−−−−−−−−−− ↓\downarrow ↓…...