C++ Lambda表达式的完整介绍
一、Lambda表达式概述
c++在c++11标准中引入了lambda表达式,一般用于定义匿名函数,lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。本文主要介绍Lambda的工作原理以及使用方法。
二、Lambda表达式定义
1、Lambda表达式示例
下例是MS官网上的一个示例:
#include <algorithm>
#include <cmath>void abssort(float* x, unsigned n) {std::sort(x, x + n,// Lambda expression begins[](float a, float b) {return (std::abs(a) < std::abs(b));} // end of lambda expression);
}
这个实例中直接将排序函数的实现写在应该传递函数的位置,省去了定义排序函数的过程,对于这种不需要复用,且短小的函数,直接传递函数体可以增加代码的可读性。
2、Lambda表达式语法定义
-
capture 子句(在 C++ 规范中也称为 Lambda 引导。)
-
参数列表(可选)。 (也称为 Lambda 声明符)
-
mutable 规范(可选)。
-
exception-specification(可选)。
-
return-type 返回值(可选)。
-
Lambda 体。
3、Lambda表达式参数详解
1)捕获列表
上面介绍完了lambda表达式的各个成分,其实很多部分和正常的函数没什么区别,其中最大的一个不同点就是捕获列表。我在刚开始用lambda表达式的时候,还一直以为这个没啥用,只是用一个 [] 来标志着这是一个lambda表达式。后来了解了才知道,原来这个捕获列表如此强大,甚至我觉得捕获列表就是lambda表达式的灵魂。下面先介绍几种常用的捕获方式。
[] 什么也不捕获,无法lambda函数体使用任何
[=] 按值的方式捕获所有变量
[&] 按引用的方式捕获所有变量
[=, &a] 除了变量a之外,按值的方式捕获所有局部变量,变量a使用引用的方式来捕获。这里可以按引用捕获多个,例如 [=, &a, &b,&c]。这里注意,如果前面加了=,后面加的具体的参数必须以引用的方式来捕获,否则会报错。
[&, a] 除了变量a之外,按引用的方式捕获所有局部变量,变量a使用值的方式来捕获。这里后面的参数也可以多个,例如 [&, a, b, c]。这里注意,如果前面加了&,后面加的具体的参数必须以值的方式来捕获。
[a, &b] 以值的方式捕获a,引用的方式捕获b,也可以捕获多个。
[this] 在成员函数中,也可以直接捕获this指针,其实在成员函数中,[=]和[&]也会捕获this指针。
class A{public:int i_ = 0;void func(int x, int y){auto x1 = []{ return i_; }; // error,没有捕获外部变量auto x2 = [=]{ return i_ + x + y; }; // OK,捕获所有外部变量auto x3 = [&]{ return i_ + x + y; }; // OK,捕获所有外部变量auto x4 = [this]{ return i_; }; // OK,捕获this指针auto x5 = [this]{ return i_ + x + y; }; // error,没有捕获x、yauto x6 = [this, x, y]{ return i_ + x + y; }; // OK,捕获this指针、x、yauto x7 = [this]{ return i_++; }; // OK,捕获this指针,并修改成员的值}};int a = 0, b = 1;auto f1 = []{ return a; }; // error,没有捕获外部变量auto f2 = [&]{ return a++; }; // OK,捕获所有外部变量,并对a执行自加运算auto f3 = [=]{ return a; }; // OK,捕获所有外部变量,并返回aauto f4 = [=]{ return a++; }; // error,a是以复制方式捕获的,无法修改auto f5 = [a]{ return a + b; }; // error,没有捕获变量bauto f6 = [a, &b]{ return a + (b++); }; // OK,捕获a和b的引用,并对b做自加运算auto f7 = [=, &b]{ return a + (b++); }; // OK,捕获所有外部变量和b的引用,并对b做自加运算
2)参数列表
Lambda 既可以捕获变量,也可以接受输入参数。 参数列表(在标准语法中称为 Lambda 声明符)是可选的,它在大多数方面类似于函数的参数列表。
auto function = [] (int first, int second){return first + second;
};function(100, 200);
3)可变规格mutable
mutable修饰符, 默认情况下Lambda函数总是一个const函数,mutable可以取消其常量性。在使用该修饰符时,参数列表不可省略(即使参数为空)。
#include <iostream>
using namespace std;int main()
{int m = 0;int n = 0;[&, n] (int a) mutable { m = ++n + a; }(4);cout << m << endl << n << endl;
}
4)异常说明
你可以使用 throw() 异常规范来指示 lambda 表达式不会引发任何异常。与普通函数一样,如果 lambda 表达式声明 C4297 异常规范且 lambda 体引发异常,Visual C++ 编译器将生成警告 throw() 。
int main() // C4297 expected
{ []() throw() { throw 5; }();
}
5)返回类型
Lambda表达式的返回类型会自动推导。除非你指定了返回类型,否则不必使用关键字。返回型类似于通常的方法或函数的返回型部分。但是,返回类型必须在参数列表之后,并且必须在返回类型->之前包含类型关键字。如果lambda主体仅包含一个return语句或该表达式未返回值,则可以省略Lambda表达式的return-type部分。如果lambda主体包含一个return语句,则编译器将从return表达式的类型中推断出return类型。否则,编译器将返回类型推导为void。
auto x1 = [](int i){ return i; };
6)Lambda函数体
Lambda表达式的lambda主体(标准语法中的复合语句)可以包含普通方法或函数的主体可以包含的任何内容。普通函数和lambda表达式的主体都可以访问以下类型的变量:
- 捕获变量
- 形参变量
- 局部声明的变量
- 类数据成员,当在类内声明**`this`**并被捕获时
- 具有静态存储持续时间的任何变量,例如全局变量
#include <iostream>
using namespace std;int main()
{int m = 0;int n = 0;[&, n] (int a) mutable { m = ++n + a; }(4);cout << m << endl << n << endl;
}
相关文章:

C++ Lambda表达式的完整介绍
一、Lambda表达式概述 c在c11标准中引入了lambda表达式,一般用于定义匿名函数,lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步…...
【等保测评】云计算Linux服务器(一)
【等保测评】云计算&Linux服务器(一) 前言1、身份鉴别实例1实例2实例3实例4 2、访问控制实例1实例2实例3实例4实例5实例6实例7 前言 Linux是指UNIX克隆或类UNIX风格的操作系统,在源代码级别兼容绝大部分UNIX标准(IEEE POSIX, System V, …...

[vue-element-admin]下载与安装
一、环境搭建 1 nodejs 源码地址 sudo apt install build-essential # 内含gcc g make等全家桶git clone git://github.com/nodejs/node.git # 下载源码 cd node sudo ./config sudo make && make install # 编译 node -v # 查看是否编译成功二、遇见的问题 问题…...
OPENCV C++(九)鼠标响应+dft+idft
鼠标响应回调函数(固定格式) void on_mouse(int EVENT, int x, int y, int flags, void* userdata) {Mat hh;hh *(Mat*)userdata;Point p(x, y);switch (EVENT){case EVENT_LBUTTONDOWN:{points.x x;points.y y;mousePoints.push_back(points);circle…...

python编程求出介于这两个数 之间的所有质数并打印输出。显示格式为“*数是质数
这里写自定义目录标题 练习 :提示用户输入两个正整数,编程求出介于这两个数之间的所有质数并打印输出。显示格式为“*数是质数。”代码打印效果 练习 :提示用户输入两个正整数,编程求出介于这两个数之间的所有质数并打印输出。显示…...

基于Selenium模块实现无界面模式 执行JS脚本
此篇文章主要介绍如何使用 Selenium 模块实现 无界面模式 & 执行JS脚本(把滚动条拉到底部),并以具体的示例进行展示。 1、Selenium 设置无界面模式 创建浏览器对象之前,创建 options 功能对象 :options webdriver.ChromeOptions() 添加…...

【LangChain学习】基于PDF文档构建问答知识库(二)创建项目
这里我们使用到 fastapi 作为项目的web框架,它是一个快速(高性能)的 web 框架,上手简单。 一.创建 FastAPI 项目 我们在IDE中,左侧选择 FastAPI ,右侧选择创建一个新的虚拟环境。 创建成功,会有…...

【Kubernetes】Kubernetes之kubectl详解
kubectl 一、陈述式资源管理1. 陈述式资源管理方法2. 基本信息查看3. 项目周期管理3.1 创建 kubectl create 命令3.2 发布 kubectl expose命令3.3 更新 kubectl set3.4 回滚 kubectl rollout3.5 删除 kubectl delete 4. kubectl 的发布策略4.1 蓝绿发布4.2 红黑发布4.3 灰度发布…...

【torch.nn.PixelShuffle】和 【torch.nn.UnpixelShuffle】
文章目录 torch.nn.PixelShuffle直观解释官方文档 torch.nn.PixelUnshuffle直观解释官方文档 torch.nn.PixelShuffle 直观解释 PixelShuffle是一种上采样方法,它将形状为 ( ∗ , C r 2 , H , W ) (∗, C\times r^2, H, W) (∗,Cr2,H,W)的张量重新排列转换为形状为…...
Rocky9 KVM网桥的配置
KVM的默认网络模式为NAT,借助宿主机模式上网,现在我们来改成桥接模式,这样外界就可以直接和宿主机里的虚拟机通讯了。 Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。 桥接网络(也叫物理设备共享…...

爬虫013_函数的定义_调用_参数_返回值_局部变量_全局变量---python工作笔记032
然后再来看函数,可以避免重复代码 可以看到定义函数以及调用函数...

将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例)
将.doc文档的默认打开方式从WPS修改为word office打开方式的具体方法(以win 10 操作系统为例) 随着近几年WPS软件的不断完善和丰富,在某些方面取得了具有特色的优势。在平时编辑.doc文档时候也常常用到wps软件,不过WPS文献也存在…...

如何搭建个人的GPT网页服务
写在前面 在创建个人的 GPT网页之前,我登录了 Git 并尝试了一些开源项目,但是没有找到满足我个性化需求的设计。虽然许多收费的 GPT网页提供了一些免费额度,足够我使用,但是公司的安全策略会屏蔽这些网页。因此,我决定…...
[QCM6125][Android13] 默认关闭SELinux权限
文章目录 开发平台基本信息问题描述解决方法 开发平台基本信息 芯片: QCM6125 版本: Android 13 kernel: msm-4.14 问题描述 正常智能硬件设备源码开发,到手的第一件事就是默认关闭SELinux权限,这样能够更加方便于调试功能。 解决方法 --- a/QSSI.1…...
【jvm】jvm发展历程
目录 一、Sun Classic VM二、Exact VM三、HotSpot VM四、JRockit五、J9六、KVM、CDC、CLDC七、Azul VM八、Liquid VM九、Apache Harmony十、Microsoft JVM十一、Taobao JVM十二、Dalvik VM 一、Sun Classic VM 1.1996年java1.0版本,sun公司发布了sun classic vm虚拟…...

Dubbo3.0 Demo
将SpringBoot工程集成Dubbo 1.创建父工程 2.创建子工程consumer,provider 3.初始化工程 4.引入依赖 在provider和consumer中引入dubbo依赖 <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</a…...

源码分析——ConcurrentHashMap源码+底层数据结构分析
文章目录 1. ConcurrentHashMap 1.71. 存储结构2. 初始化3. put4. 扩容 rehash5. get 2. ConcurrentHashMap 1.81. 存储结构2. 初始化 initTable3. put4. get 3. 总结 1. ConcurrentHashMap 1.7 1. 存储结构 Java 7 中 ConcurrentHashMap 的存储结构如上图,Concurr…...
R语言中的函数25:paste,paste0
文章目录 介绍paste0()实例 paste()实例 介绍 paste0()和paste()函数都可以实现对字符串的连接,paste0是paste的简化版。 paste0() paste (..., sep " ", collapse NULL, recycle0 FALSE)… one or more R objects, to be converted to character …...

(八)穿越多媒体奇境:探索Streamlit的图像、音频与视频魔法
文章目录 1 前言2 st.image:嵌入图像内容2.1 图像展示与描述2.2 调整图像尺寸2.3 使用本地文件或URL 3 st.audio:嵌入音频内容3.1 播放音频文件3.2 生成音频数据播放 4 st.video:嵌入视频内容4.1 播放视频文件4.2 嵌入在线视频 5 结语&#x…...

CAD练习——绘制房子平面图
首先还是需要设置图层、标注、文字等 XL:构造线 用构造线勾勒大致的轮廓: 使用多线命令:ML 绘制墙壁 可以看到有很多交叉点的位置 用多线编辑工具将交叉点处理 有一部分处理不了的,先讲多线分解,然后用修剪打理&…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

【SQL学习笔记1】增删改查+多表连接全解析(内附SQL免费在线练习工具)
可以使用Sqliteviz这个网站免费编写sql语句,它能够让用户直接在浏览器内练习SQL的语法,不需要安装任何软件。 链接如下: sqliteviz 注意: 在转写SQL语法时,关键字之间有一个特定的顺序,这个顺序会影响到…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...