C++11中的Lambda表达式
文章目录
- C++11中的Lambda表达式
- 1.lambda表达式形式
- 2.向lambda传递参数
- 3.使用捕获列表
- 4.lambda捕获和返回
- 1.值捕获
- 2.引用捕获
- 3.隐式捕获
- 4.可变lambda
- 5.指定lambda的返回类型
C++11中的Lambda表达式
1.lambda表达式形式
lambda表达式具有以下形式
[capture list] (parameter list) -> return type {function body}
其中,[capture list] 是捕获列表,是一个lambda所在函数中定义的局部变量的列表,通常为空。return type、(parameter list)、{function body}和普通函数一样,分别表示返回类型、参数列表、函数体。但是和普通函数不同lambda必须尾置返回。
我们可以忽略参数列表和返回类型,但是必须永远包含捕获列表和函数体。
例如:
auto f = [] {return 42;}
上述例子中,忽略参数列表,表示函数参数为空;忽略返回类型,则会根据函数体中的代码推断出返回类型。
2.向lambda传递参数
和普通的函数类似,调用lambda时给定的实参被用来初始化lambda的形参,通常实参和形参的类型必须匹配。注意:lambda函数不能有默认参数。
例如:
[](const string& a,const string& b) {return a.size() < b.size();}
空捕获列表表明lambda不使用它所在函数中的任何局部变量。
应用如下:
stable_sort(word.begin().word.end(),[](const string& a,const string& b){return a.size() < b.size();});
当stable_sort需要比较两个元素时,它就会调用给定的lambda表达式。
3.使用捕获列表
虽然lambda可以出现在一个函数中,使用其局部变量,但是它只能使用那些明确指明的变量。一个lambda通过将局部变量包含在其捕获列表中来指出将会使用这些变量。
例如:
[sz](const string& a){return a.size() >= sz; }
lambda将捕获sz,函数体将string的大小与sz进行比较。
lambda以[] 开始,我们可以在其中添加以逗号分隔的名字列表,这些名字都是它所在函数中定义的。注意:一个lambda只有在其捕获列表中捕获一个它所在函数中的局部变量,才能在函数体中使用该变量。
另外,一个lambda可以使用定义在函数之外的名字。例如:
for_each(wc,words.begin(),[](const string& s){cout<<s<<"";});
4.lambda捕获和返回
| lambda捕获列表 | |
|---|---|
| [] | 空捕获列表。lambda不能使用所在函数中的变量,一个lambda只有捕获变量后才能使用他们 |
| [names] | names是一个逗号分隔的名字列表,这些名字都是lambda所在函数的局部变量。默认情况下,捕获列表中的变量都被拷贝。名字前如果使用了&,则采用引用捕获方式。 |
| [&] | 隐式捕获列表,采用引用捕获方式。lambda体中所使用的来自所在函数的实体都采用引用的方式使用。 |
| [=] | 隐式捕获列表,采用值捕获方式。lambda体中所使用的来自所在函数的实体都采用拷贝的方式使用。 |
| [&,identifier_list] | identifier_list 是一个逗号分隔的列表,包含0个或者多个来自所在函数的变量,这些变量采用值捕获方式,而任何隐式捕获的变量都采用引用方式捕获。identifier_list中的名字前面不能使用&。 |
| [=,identifier_list] | identifier_list 是一个逗号分隔的列表,包含0个或者多个来自所在函数的变量,这些变量采用引用捕获方式,而任何隐式捕获的变量都采用值方式捕获。identifier_list中的名字不能包括this,且这些名字之前必须使用&。 |
1.值捕获
类似参数传递,捕获方式也可以是值捕获或者引用。采用值捕获的前提是变量可以被拷贝。与参数不同,被捕获的变量的值是在lambda创建时拷贝,而不是调用时拷贝。
例如:
void fun1
{size_t v1 = 42;auto f = [v1]{return v1;};v1 = 0;auto j = f(); // j的值为42,f保存了我们创建时v1的拷贝
}
2.引用捕获
正如上述例子,我们使用引用捕获:
void fun1
{size_t v1 = 42;auto f = [&v1]{return v1;};v1 = 0;auto j = f(); // j的值为0,f保存了我们创建时v1的引用,而非拷贝
}
引用捕获的限制:必须确保被引用的对象,在lambda函数执行时是存在的。
建议:尽量保持lambda的变量捕获简单化。捕获一个普通变量,如int、string或者其他非指针类型,通常可以采用简单的值捕获方式,在此情况下只需关注变量在捕获时,是否有我们所需值就可以了。如果我们捕获一个指针或者迭代器,或采用引用捕获的方式,就必须确保在lambda执行时,绑定到迭代器、指针或引用的对象仍然存在。
应该避免捕获指针或者引用。
3.隐式捕获
除了可以显示列出我们要使用的变量之外,我们还可以让编译器根据lambda函数体中的代码推断我们要使用哪些变量,为了指示编译器推断捕获列表,应在捕获列表中写一个&或者=,&告诉编译器采用引用方式,=则表示采用值捕获方式。例如:
// sz 为隐式捕获,值捕获方式
wc = find_if(words.begin(),words.end(),[=](const string& s){return s.size()>sz;});
如果我们希望对一部分变量采用值捕获方式,对其他变量采用引用捕获方式,可以混合使用隐式捕获和显示捕获。
例如:
// os隐式捕获,引用捕获方式;c显示捕获,值捕获方式
for_each(wc,words.begin(),
[&,c](const string& s){os << s << c;});
// os显式捕获,引用捕获方式;c隐式捕获,值捕获方式
for_each(wc,words.begin(),
[=,&os](const string& s){os << s << c;});
当我们混合使用隐式和显示捕获时,捕获列表的第一个元素必须是&或=,此符号指定了默认捕获方式为引用或值。并且显示捕获的变量和隐式捕获的变量必须使用不同的捕获方式。
4.可变lambda
默认情况下,对于值捕获lambda不会改变其值,如果我们希望改变一个被捕获变量的值,就必须在参数列表尾加上关键字mutable。例如:
void fun1
{size_t v1 = 42;// f可以改变她所捕获的变量的值auto f = [v1]() mutable {return ++v1;};v1 = 0;auto j = f(); // j的值为43
}
另外,一个引用捕获的变量是否可以修改依赖于此引用指向的是const类型还是非const类型。例如:
void fun1
{size_t v1 = 42;// v1是一个非const变量的引用,可以通过f中的引用来改变它auto f = [&v1]() {return ++v1;};v1 = 0;auto j = f(); // j的值为1
}
5.指定lambda的返回类型
一般情况下lambda返回为void,但是也有需要指定返回类型的时候。
注意:当我们需要为lambda定义返回类型时,必须使用尾置返回类型。例如:
tansform(v1.begin(),v1.end(),v1.begin(),[](int i) -> int
{if(i < 0) return -i;
else
return i;});
好了,lambda表达式的介绍就到这里。以上所有内容均来自《C++ primer》第5版一书,更详细的内容,可以参考该书。
相关文章:
C++11中的Lambda表达式
文章目录 C11中的Lambda表达式1.lambda表达式形式2.向lambda传递参数3.使用捕获列表4.lambda捕获和返回1.值捕获2.引用捕获3.隐式捕获4.可变lambda5.指定lambda的返回类型 C11中的Lambda表达式 1.lambda表达式形式 lambda表达式具有以下形式 [capture list] (parameter list)…...
Unity图形系统
Unity的图形系统是一个复杂且功能强大的模块,它支持多种渲染技术和API,能够满足从移动设备到高端游戏机和桌面平台的各种需求。以下是关于Unity图形系统的详细解析: 渲染流程与技术 Unity的渲染流程可以分为应用程序阶段(CPU&…...
Ceph篇之利用shell脚本实现批量创建bucket桶
Ceph创建bucket桶 在 Ceph 中创建桶(bucket)需要使用 Ceph 对象网关(RGW)。 注:如果查看shell批量创建脚本请直接参见目录3 1. 利用radosgw-admin工具创建桶 确保 Ceph 集群和对象网关已正确配置 确保你的 Ceph 集群…...
周末总结(2024/08/17)
工作 人际关系核心实践: 要学会随时回应别人的善意,执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己,抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内,职场社交不要放在5min以内 职场的人际关系在面对利…...
SQL高级编程:掌握自定义函数和过程的艺术
标题:SQL高级编程:掌握自定义函数和过程的艺术 在SQL的世界里,数据操作不仅仅局限于简单的查询和更新。通过自定义函数(User-Defined Functions, UDFs)和存储过程(Stored Procedures)ÿ…...
python监听环境内是否有声音
python监听环境内是否有声音 首先使用pyaudio打开麦克风,并开始录音。然后使用一个while循环来不断读取麦克风录取的音频数据,然后使用numpy来分析音频数据是否有声音。当检测到有声音时,会打印"有声音"并退出循环。最后关闭录音流…...
合并两个有序链表--力扣
题目如下: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例如下: 示例 1: 输入:l1 [1,2,4], l2 [1,3,4] 输出:[1,1,2,3,4,4]示例 2: 输入:l1 [], l2 …...
【自用】Python爬虫学习(三):图片下载、使用代理、防盗链视频下载、多线程与多进程
Python爬虫学习(三) 使用BeautifulSoup解析网页并下载图片模拟用户登录处理使用代理视频下载,防盗链的处理多线程与多进程 使用BeautifulSoup解析网页并下载图片 目的:对某网站的某个专栏页面的图片进行下载得到高清图。 思路&am…...
#Datawhale AI夏令营第4期#AIGC方向Task3
在之前的任务中,我们已经对baseline进行了精读,并生成了,我们自己的八图故事。 在Task3中,我们的主要任务有两个:part1:工具初探一ComfyUI应用场景探索;Part2:Lora微调。 微调是一…...
【docker综合篇】关于我用docker搭建了6个应用服务的事
最近一直在捣鼓docker,利用测试服务器,本着犯错就重来(重装系统)的大无畏精神,不断尝试,总结经验,然后在网上搜寻一些关于docker有关的服务镜像,并搭建起来。看着一个个服务在我的服务器跑起来,…...
【sgCreateAPIFunction】自定义小工具:敏捷开发→自动化生成API接口方法代码片段脚本(接口方法代码生成工具)
sgCreateAPIFunction源码 <template><!-- 前往https://blog.csdn.net/qq_37860634/article/details/141159084 查看使用说明 --><div :class"$options.name"><div class"sg-head">接口方法生成工具<el-dropdown:show-timeou…...
Vue2图片懒加载(vue-lazyload)
参考文档:vue-lazyload 安装插件 npm install vue-lazyload # or yarn add vue-lazyload # or pnpm add vue-lazyload使用 使用方式 一: 所有懒加载图片的占位图使用同一张默认图片 引入并注册 // main.js import VueLazyload from vue-lazyload Vue…...
Jenkins-拉取代码
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、Jenkins环境配置(一)配置Maven环境(1)Maven下载(2)将Maven上传服务器(3&…...
深度解析:.secret勒索病毒如何加密你的数据并勒索赎金
引言: 在当今这个数字化、信息化的时代,网络安全已成为一个不容忽视的重要议题。随着互联网的普及和技术的飞速发展,我们的生活、工作乃至整个社会的运转都越来越依赖于各种计算机系统和网络。然而,这种高度依赖也为我们带来了前…...
测试岗位应该学什么
以下是测试岗位需要学习的一些关键内容: 1. 测试理论和方法 - 了解不同类型的测试,如功能测试、性能测试、压力测试、安全测试、兼容性测试等。 - 掌握测试策略和测试计划的制定。 2. 编程语言 - 至少熟悉一种编程语言,如 Python、Java…...
【RISC-V设计-12】- RISC-V处理器设计K0A之验证环境
【RISC-V设计-12】- RISC-V处理器设计K0A之验证环境 文章目录 【RISC-V设计-12】- RISC-V处理器设计K0A之验证环境1.简介2.验证顶层3.顶层代码4.模型结构4.1 地址映射4.2 特殊功能寄存器 5.模型代码6.运行脚本7.总结 1.简介 在前几篇文章中,分别介绍了各个模块的设…...
react-redux的使用
关于react-redux 首先:react-redux和redux并不是一个东西,redux是一个独立的东西,react-redux是react官方根据市场偏好redux推出的react插件库。 了解react-redux的原理图: 安装:npm i react-redux redux的ui组件和…...
大模型在chat bi 场景下的优化思路
文章目录 背景提示词模版表结构注释示例数据给出示例答案语法验证外挂知识库 背景 大模型的出现使chat bi 成为一种可能,自然语句的交互,极大的提高了数据分析的效率,也极大的降低了用户使用的门槛。下面主要列出几点提高自然语句转成SQL的技…...
Qt登录窗口
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget),btn(new QPushButton("取消", this)),login_btn(new QPushButton("登录", this)) { ui->setupUi(this);thi…...
Zookeeper的在Ubuntu20.04上的集群部署
安装资源 官方安装包下载地址:https://zookeeper.apache.org/releases.html 懒得找版本的可以移步下载zookeeper3.84稳定版本: https://download.csdn.net/download/qq_43439214/89646735 安装方法 创建安装路径&&解压安装包 # 创建路径 m…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
大型活动交通拥堵治理的视觉算法应用
大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
【CSS position 属性】static、relative、fixed、absolute 、sticky详细介绍,多层嵌套定位示例
文章目录 ★ position 的五种类型及基本用法 ★ 一、position 属性概述 二、position 的五种类型详解(初学者版) 1. static(默认值) 2. relative(相对定位) 3. absolute(绝对定位) 4. fixed(固定定位) 5. sticky(粘性定位) 三、定位元素的层级关系(z-i…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
大学生职业发展与就业创业指导教学评价
这里是引用 作为软工2203/2204班的学生,我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要,而您认真负责的教学态度,让课程的每一部分都充满了实用价值。 尤其让我…...
Java毕业设计:WML信息查询与后端信息发布系统开发
JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发,实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构,服务器端使用Java Servlet处理请求,数据库采用MySQL存储信息࿰…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
