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

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的图形系统是一个复杂且功能强大的模块&#xff0c;它支持多种渲染技术和API&#xff0c;能够满足从移动设备到高端游戏机和桌面平台的各种需求。以下是关于Unity图形系统的详细解析&#xff1a; 渲染流程与技术 Unity的渲染流程可以分为应用程序阶段&#xff08;CPU&…...

Ceph篇之利用shell脚本实现批量创建bucket桶

Ceph创建bucket桶 在 Ceph 中创建桶&#xff08;bucket&#xff09;需要使用 Ceph 对象网关&#xff08;RGW&#xff09;。 注&#xff1a;如果查看shell批量创建脚本请直接参见目录3 1. 利用radosgw-admin工具创建桶 确保 Ceph 集群和对象网关已正确配置 确保你的 Ceph 集群…...

周末总结(2024/08/17)

工作 人际关系核心实践&#xff1a; 要学会随时回应别人的善意&#xff0c;执行时间控制在5分钟以内 坚持每天早会打招呼 遇到接不住的话题时拉低自己&#xff0c;抬高别人(无阴阳气息) 朋友圈点赞控制在5min以内&#xff0c;职场社交不要放在5min以内 职场的人际关系在面对利…...

SQL高级编程:掌握自定义函数和过程的艺术

标题&#xff1a;SQL高级编程&#xff1a;掌握自定义函数和过程的艺术 在SQL的世界里&#xff0c;数据操作不仅仅局限于简单的查询和更新。通过自定义函数&#xff08;User-Defined Functions, UDFs&#xff09;和存储过程&#xff08;Stored Procedures&#xff09;&#xff…...

python监听环境内是否有声音

python监听环境内是否有声音 首先使用pyaudio打开麦克风&#xff0c;并开始录音。然后使用一个while循环来不断读取麦克风录取的音频数据&#xff0c;然后使用numpy来分析音频数据是否有声音。当检测到有声音时&#xff0c;会打印"有声音"并退出循环。最后关闭录音流…...

合并两个有序链表--力扣

题目如下: 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例如下: 示例 1&#xff1a; 输入&#xff1a;l1 [1,2,4], l2 [1,3,4] 输出&#xff1a;[1,1,2,3,4,4]示例 2&#xff1a; 输入&#xff1a;l1 [], l2 …...

【自用】Python爬虫学习(三):图片下载、使用代理、防盗链视频下载、多线程与多进程

Python爬虫学习&#xff08;三&#xff09; 使用BeautifulSoup解析网页并下载图片模拟用户登录处理使用代理视频下载&#xff0c;防盗链的处理多线程与多进程 使用BeautifulSoup解析网页并下载图片 目的&#xff1a;对某网站的某个专栏页面的图片进行下载得到高清图。 思路&am…...

#Datawhale AI夏令营第4期#AIGC方向Task3

在之前的任务中&#xff0c;我们已经对baseline进行了精读&#xff0c;并生成了&#xff0c;我们自己的八图故事。 在Task3中&#xff0c;我们的主要任务有两个&#xff1a;part1&#xff1a;工具初探一ComfyUI应用场景探索&#xff1b;Part2&#xff1a;Lora微调。 微调是一…...

【docker综合篇】关于我用docker搭建了6个应用服务的事

最近一直在捣鼓docker&#xff0c;利用测试服务器&#xff0c;本着犯错就重来(重装系统)的大无畏精神&#xff0c;不断尝试&#xff0c;总结经验&#xff0c;然后在网上搜寻一些关于docker有关的服务镜像&#xff0c;并搭建起来。看着一个个服务在我的服务器跑起来&#xff0c;…...

【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)

参考文档&#xff1a;vue-lazyload 安装插件 npm install vue-lazyload # or yarn add vue-lazyload # or pnpm add vue-lazyload使用 使用方式 一&#xff1a; 所有懒加载图片的占位图使用同一张默认图片 引入并注册 // main.js import VueLazyload from vue-lazyload Vue…...

Jenkins-拉取代码

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Jenkins环境配置&#xff08;一&#xff09;配置Maven环境&#xff08;1&#xff09;Maven下载&#xff08;2&#xff09;将Maven上传服务器&#xff08;3&…...

深度解析:.secret勒索病毒如何加密你的数据并勒索赎金

引言&#xff1a; 在当今这个数字化、信息化的时代&#xff0c;网络安全已成为一个不容忽视的重要议题。随着互联网的普及和技术的飞速发展&#xff0c;我们的生活、工作乃至整个社会的运转都越来越依赖于各种计算机系统和网络。然而&#xff0c;这种高度依赖也为我们带来了前…...

测试岗位应该学什么

以下是测试岗位需要学习的一些关键内容&#xff1a; 1. 测试理论和方法 - 了解不同类型的测试&#xff0c;如功能测试、性能测试、压力测试、安全测试、兼容性测试等。 - 掌握测试策略和测试计划的制定。 2. 编程语言 - 至少熟悉一种编程语言&#xff0c;如 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.简介 在前几篇文章中&#xff0c;分别介绍了各个模块的设…...

react-redux的使用

关于react-redux 首先&#xff1a;react-redux和redux并不是一个东西&#xff0c;redux是一个独立的东西&#xff0c;react-redux是react官方根据市场偏好redux推出的react插件库。 了解react-redux的原理图&#xff1a; 安装&#xff1a;npm i react-redux redux的ui组件和…...

大模型在chat bi 场景下的优化思路

文章目录 背景提示词模版表结构注释示例数据给出示例答案语法验证外挂知识库 背景 大模型的出现使chat bi 成为一种可能&#xff0c;自然语句的交互&#xff0c;极大的提高了数据分析的效率&#xff0c;也极大的降低了用户使用的门槛。下面主要列出几点提高自然语句转成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上的集群部署

安装资源 官方安装包下载地址&#xff1a;https://zookeeper.apache.org/releases.html 懒得找版本的可以移步下载zookeeper3.84稳定版本&#xff1a; https://download.csdn.net/download/qq_43439214/89646735 安装方法 创建安装路径&&解压安装包 # 创建路径 m…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

css的定位(position)详解:相对定位 绝对定位 固定定位

在 CSS 中&#xff0c;元素的定位通过 position 属性控制&#xff0c;共有 5 种定位模式&#xff1a;static&#xff08;静态定位&#xff09;、relative&#xff08;相对定位&#xff09;、absolute&#xff08;绝对定位&#xff09;、fixed&#xff08;固定定位&#xff09;和…...

代理篇12|深入理解 Vite中的Proxy接口代理配置

在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)

上一章用到了V2 的概念&#xff0c;其实 Fiori当中还有 V4&#xff0c;咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务)&#xff0c;代理中间件&#xff08;ui5-middleware-simpleproxy&#xff09;-CSDN博客…...