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

C++ Lambda表达式第二篇, Lambda表达式

C++ Lambda表达式

  • Lambda 捕获
  • 含有模板参数的Lambda表达式
  • 无模板参数的Lambda表达式

Lambda 捕获

captures是零个或多个捕获的逗号分隔列表,可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是

  • &,变量引用方式,隐式捕获已使用的变量,存储持续时间限于Lambda表达式内
  • =,值引用方式,隐式捕获已使用的变量,存储持续时间限于Lambda表达式内。

如果存在任一捕获默认值,则当前对象 (*this)可以隐式捕获。如果隐式捕获,则始终通过引用捕获,即使捕获默认值为=。从C++20开始,当捕获默认值为 = 时,不推荐使用 *this 的隐式捕获。

captures 中单个捕获的语法是

下面展示一些 内联代码片

 - identifier                            简单的值引用捕获- identifier ...                        简单的值引用捕获,捕获是一个包扩展- identifier initializer                简单的值引用捕获,捕获包括初始化器- &identifier                           简单的变量引用捕获- &identifier...                        简单的变量引用捕获,捕获是一个包扩展- &identifier initializer               简单的变量引用捕获,捕获包括初始化器- this                                  当前对象的简单的变量引用捕获- *this                                 当前对象的简单的值引用捕获- ...identifier initializer             值引用捕获,捕获是一个包扩展, 包扩展包含初始化器- &...identifier initializer            变量引用捕获,捕获是一个包扩展, 包扩展包含初始化器

如果capture-default 为 &,则后续的简单捕获不能以 & 开头。

#include  <iostream>using namespace std;struct S2 { void f(int i, int j); };
void S2::f(int i, int j)
{[&] {i = i + 1;};          // OK: by-reference capture defaultcout << "i = " << i << endl;//	[&, i] {i=0; j=j+1;};       // error: assignment of read-only variable ‘i’[&, i] {j=i+1;};cout << "j=" << j << endl;//	[&, &i] {};      // Error: by-reference capture when by-reference is the default[=, &j] {j=i+1;};cout << "j=" << j << endl;[&, this, i] {}; // OK, equivalent to [&, i]
}int main() {	S2 s1;s1.f(1, 2);cout << endl;s1.f(9, 10);
}

代码运行的屏幕输出

i = 1
j=2
j=2i = 9
j=10
j=10

只有在块作用域或默认成员初始器中定义的 lambda 表达式,才可以有一个默认捕获或不带初始器的捕获。对于此类 lambda 表达式,其有效范围定义为一组封闭范围,这个范围包括最内层封闭函数(及其参数)。这包括嵌套的块作用域和封闭 lambda 的作用域(如果该 lambda 是嵌套的)。

任何没有初始化程序的捕获(除了 this-capture)中的 identifier,都是在 lambda 的到达范围内,使用通常的非限定名称查找来查找的。查找的结果必须是,在到达范围内声明的具有自动存储持续时间的变量,或者是其对应变量满足此类要求的结构化绑定。该实体被显式捕获。

带初始器的捕获的行为,就好像它声明,并显式捕获一个变量,这个变量使用类型说明符 auto 和相同的初始器声明。其声明区域是 lambda 表达式的主体(即,它不在其初始器设定的范围内),但不包括下列情况:

  • 如果捕获是通过值引用,则闭包对象引入的非静态数据成员,是引用该变量的另一种方式;
    换句话说,源变量实际上并不存在,并且通过 auto 进行类型推导和初始化,适用于该非静态数据成员;
  • 如果捕获是通过变量引用,则闭包对象的生命周期结束时,引用变量的生命周期也结束。

这用于通过 x = std::move(x) 等捕获,来捕获仅移动类型。
这也使得可以使用 &cr = std::as_const(x) 或类似方法,使const 引用捕获成为可能。

#include  <iostream>using namespace std;int x = 4;
auto y = [&r = x, x = x + 1]()->int{r += 2; return x * x;};int main()
{auto val = y();cout << "x=" << x  <<  endl;cout << val << endl;
}
x=6
25

如果捕获表有一个默认捕获,并且未显式捕获封闭对象(如 this 或 *this),或者自动变量,或者结构化绑定;那么,它会隐式捕获实体, 该实体在一个表达式中,在potentially-evaluated表达式中命名。
该自动变量在lambda 主体中是odr-usable。结构化绑定有原子存储持续时间。

#include  <iostream>using namespace std;void f(int x, const int (&)[2] = {}) { cout <<"f1:" << x <<endl;}   // #1
void f(const int &x, const int (&)[1]) { cout <<"f2:" << x <<endl;} // #2struct NoncopyableLiteralType
{constexpr explicit NoncopyableLiteralType(int n) : n_(n) {}NoncopyableLiteralType(const NoncopyableLiteralType&) = delete;int n_;
};int main ()
{const int x = 17;auto l0 = []{ f(x); };           // OK: calls #1, does not capture xauto g0 = [](auto a) { f(x); };  // same as aboveauto l1 = [=]{ f(x); };          // OK: captures x (since P0588R1) and calls #1// the capture can be optimized awayauto g1 = [=](auto a) { f(x); }; // same as aboveauto g2 = [=](auto a) {int selector[sizeof(a) == 1 ? 1 : 2] = {};f(x, selector); 					// OK: is a dependent expression, so captures xcout << "g2" << endl;};auto ltid = [=]{ return typeid(x).name(); };   // OK: captures x (since P0588R1)// even though x is unevaluated// the capture can be optimized awayauto g3 = [=](auto a) {auto type = typeid(a + x).name();  // captures x regardless of// whether a + x is an unevaluated operandcout << "g3: " << type << endl;};auto g4 = [&](auto a) {int selector[sizeof(a) == 1 ? 1 : 2] = {};f(x, selector); 					// OK: is a dependent expression, so captures xcout << "g2" << endl;};l1();g1(1);g2(1);g2(2);cout << "x id:" << ltid() << endl;g3(4);g4(1);constexpr NoncopyableLiteralType w{42};auto l4 = []{ return w.n_; };      // OK: w is not odr-used, capture is unnecessary// auto l5 = [=]{ return w.n_; };  // error: w needs to be captured by copycout << l4() << endl;
}
f1:17
f1:17
f1:17
g2
f1:17
g2
x id:i
g3: i
f1:17
g2
42

含有模板参数的Lambda表达式

 - [captures ] front-attr (optional) (params ) specs (optional) exception (optional) back-attr (optional) trailing-type (optional) requires (optional) { body }- [captures ] { body }- [captures ] front-attr (optional) trailing-type (optional) { body }	- [captures ] front-attr (optional) exception back-attr (optional) trailing-type (optional) { body }	- [captures ] front-attr (optional) specs exception (optional) back-attr (optional) trailing-type (optional) { body }
  • captures - Lambda表达式可以拥有零个或多个逗号分隔的捕获列表,可以选择以捕获默认值开头。
    lambda 表达式可以使用变量而不捕获它,如果该变量
  • 是非局部变量或具有静态或线程局部存储持续时间(在这种情况下无法捕获该变量),或者
  • 是已使用常量表达式初始化的引用。

lambda 表达式可以读取变量的值而不捕获它,如果变量

  • 具有 const 非易失性整型或枚举类型,并且已使用常量表达式进行初始化,或者

  • 是 constexpr 并且没有可变成员。

  • tparams - 模板参数的非空逗号分隔列表,用于为通用 lambda 的模板参数提供名称。

  • t-requires - 给tparams 添加约束。
    如果 t-requires 以属性说明符序列结尾,则序列中的属性将被视为 front-attr 中的属性。

  • front-attr - 属性说明符序列适用于闭包类型的operator()。

  • params - 闭包类型的operator()的参数列表。
    它可以有一个显式的对象参数。

  • specs - 以下说明符的列表,每个说明符在每个序列中最多允许出现一次。

说明符意义
mutable允许 body 修改通过复制捕获的对象,并调用它们的非常量成员函数。如果存在显式对象参数,则无法使用。
constexpr显式指定 operator() 是 constexpr 函数。如果 operator() 满足所有 constexpr 函数要求,则即使 constexpr 不存在,operator() 也将是constexpr 。
consteval指定 operator() 是立即函数。consteval 和 constexpr 不能同时使用。
static指定 operator() 是静态成员函数。static 和 mutable 不能同时使用。如果 captures 不为空,或者存在显式对象参数,则无法使用。
  • exception - 为闭包类型的operator()提供动态异常规范,或noexcept说明符。

  • back-attr - 属性说明符序列适用于闭包(Closure)类型的operator()类型(因此不能使用noreturn属性)。

  • Trailing-type - -> ret,其中 ret 指定返回类型。

  • require - 给闭包类型的 operator() 添加约束。

  • body - 函数体。

在 body 的开头隐式定义 __func __

无模板参数的Lambda表达式

 - [captures ] <tparams > t-requires (optional) front-attr (optional) (params ) specs (optional) exception (optional) back-attr (optional) trailing-type (optional) requires (optional) { body }- [captures ] <tparams > t-requires (optional) { body }- [captures ] <tparams > t-requires (optional) front-attr (optional) trailing-type (optional) { body }	- [captures ] <tparams > t-requires (optional) front-attr (optional) exception back-attr (optional) trailing-type (optional) { body } - [captures ] <tparams > t-requires (optional) front-attr (optional) specs exception (optional) back-attr (optional) trailing-type (optional) { body }

相关文章:

C++ Lambda表达式第二篇, Lambda表达式

C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获 captures是零个或多个捕获的逗号分隔列表&#xff0c;可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是 &&#xff0c;…...

Linux系统的介绍和常用命令

文章目录 介绍常用命令文件和目录操作文件内容操作系统管理命令网络命令 &#x1f388;个人主页&#xff1a;程序员 小侯 &#x1f390;CSDN新晋作者 &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 ✨收录专栏&#xff1a;Liunx系统 ✨文章内容&#xff1a;Liunx系统介绍 &…...

IDEA安装IDE Eval Reset插件,30天自动续期,无限激活

第一步&#xff1a; 下载idea 注意&#xff1a;版本要是2021.2.2以下 第二步&#xff1a;快捷键CtrlAlts打开设置 第三步&#xff1a;打开下图中蓝色按钮 第四步&#xff1a;点击弹窗的 “” &#xff0c;并输入 plugins.zhile.io 点击 “ok” 第五步&#xff1a;搜索IDE Ea…...

【C++】初步认识C++

1. 初识C1.1 C概念相关1.2 C发展史及其重要性1.2.1 发展史1.2.2 重要性 2. C关键字3. 命名空间4. 输入和输出 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【C学习】 1. 初识C 1.1 C概念相关 C语言是结构化和模块化的语言&#xff0c;适合处理较小规模的程序。 【来源】…...

【Python数据分析与可视化】:使用【Matplotlib】实现销售数据的全面分析 ——【Matplotlib】数模学习

目录 安装Matplotlib 1.打开PyCharm&#xff1a; 2.打开终端&#xff1a; 3.安装Matplotlib&#xff1a; 4.确认安装&#xff1a; 导入Matplotlib 创建简单的折线图 代码解析&#xff1a; 创建子图 代码解析&#xff1a; 创建柱状图 代码解析&#xff1a; 创建散点…...

Docker加速器配置指南:提升镜像下载速度的秘诀 加速安装Mysql Redis ES

在安装 Docker 镜像时&#xff0c;由于官方镜像下载速度较慢&#xff0c;我们可以使用阿里云的镜像加速器来提升下载速度。 使用阿里云镜像加速器 首先&#xff0c;找到并配置阿里云的镜像加速器。安装教程如下&#xff1a; 登录阿里云&#xff0c;进入容器镜像服务。直达链…...

32单片机,C语言与汇编联合编译的几种方式

适用编译器&#xff1a;Keil5 方式一&#xff1a; 单独创建一个.s汇编文件&#xff0c;在汇编文件内对函数进行EXPORT声明 r0寄存器是函数传入的第一个参数&#xff0c;r1寄存器是函数传入的第二个参数&#xff0c;以次类推。参数最多不确定是到r4为止&#xff0c;还是到r12…...

基于GWO-CNN-BiLSTM数据回归预测(多输入单输出)-灰狼优化算法优化CNN-BiLSTM

基于GWO-CNN-BiLSTM数据回归预测(多输入单输出)-灰狼优化算法优化CNN-BiLSTM 1.数据均为Excel数据&#xff0c;直接替换数据就可以运行程序。 2.所有程序都经过验证&#xff0c;保证程序可以运行。 3.具有良好的编程习惯&#xff0c;程序均包含简要注释。 获取方式 https:/…...

自动控制:反馈控制

自动控制&#xff1a;反馈控制 反馈控制&#xff08;Feedback Control&#xff09;是一种在控制系统中通过测量输出信号&#xff0c;并将其与期望信号进行比较&#xff0c;产生误差信号&#xff0c;再根据误差信号调整输入来达到控制目标的方法。反馈控制是自动控制系统中最常…...

sqlite 数据库 介绍

文章目录 前言一、什么是 SQLite &#xff1f;二、语法三、SQLite 场景四、磁盘文件 前言 下载 目前已经出到了&#xff0c; Version 3.46.0 SQLite&#xff0c;是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是…...

【机器学习】机器学习重塑广告营销:精准触达,高效转化的未来之路

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀目录 &#x1f4d2;1. 引言&#x1f4d9;2. 机器学习基础与广告营销的结合&#x1f9e9;机器学习在广告营销中的核心应用领域&#x1f339;用…...

常见的Java运行时异常

常见的Java运行时异常 1、ArithmeticException&#xff08;算术异常&#xff09;2、ClassCastException &#xff08;类转换异常&#xff09;3、IllegalArgumentException &#xff08;非法参数异常&#xff09;4、IndexOutOfBoundsException &#xff08;下标越界异常&#xf…...

CANoe的capl调用Qt制作的dll

闲谈 因为Qt封装了很多个人感觉很好用的库&#xff0c;所以一直想通过CAPL去调用Qt实现一些功能&#xff0c;但是一直没机会&#xff08;网络上也没看到这方面的教程&#xff09;&#xff0c;这次自己用了两天&#xff0c;踩了很多坑&#xff0c;终于是做成了一个初步的调用方…...

论如何搭建属于自己的服务器?

在现如今的数字化时代中&#xff0c;为了能够搭建网站和运行应用程序&#xff0c;很多人选择搭建属于自己的服务器&#xff0c;下面我们就来了解一下如何搭建服务器吧&#xff01; 搭建服务器我们首先需要选择适合自身需求的硬件设备&#xff0c;其中包含内存、CPU和存储等配置…...

【C++ OpenCV】机器视觉-二值图像和灰度图像的膨胀、腐蚀、开运算、闭运算

原图 结果图 //包含头文件 #include <opencv2/opencv.hpp>//命名空间 using namespace cv; using namespace std;//全局函数声明部分//我的腐蚀运算 Mat Erode(Mat src, Mat Mask, uint32_t x0, uint32_t y0) {uint32_t x 0, y 0;Mat dst(src.rows, src.cols, CV_8U…...

STMF4学习笔记RTC(天空星)

前言&#xff1a;本篇笔记参考嘉立创文档&#xff0c;连接放在最后 #RTC相关概念定义 Real-Time Clock 缩写 RTC 翻译 实时时钟&#xff0c;是单片机片内外设的一种&#xff0c;作用于提供准确的时间还有日期&#xff0c;这个外设有独立的电源&#xff0c;当单片机停止供电…...

vue数组变化的侦测***

数组变化的侦测 变更方法 vue能够侦听响应式数组的变更方法&#xff0c;并在他们被调用时触发相关更新。这些变更方法包括&#xff1a; push()pop()shift()unshift()splice()sort()reverse() 替换一个数组 变更方法&#xff0c;顾名思义&#xff0c;就是会对调用他们的原数组进…...

k8s-第十节-Ingress

Ingress 介绍 Ingress 为外部访问集群提供了一个 统一 入口&#xff0c;避免了对外暴露集群端口&#xff1b;功能类似 Nginx&#xff0c;可以根据域名、路径把请求转发到不同的 Service。可以配置 https 跟 LoadBalancer 有什么区别&#xff1f; LoadBalancer 需要对外暴露…...

webrtc gcc详解

webrtc的gcc算法(Google Congestion Control)&#xff0c;貌似国内很多文章都没有细讲&#xff0c;原理是怎么样的&#xff0c;具体怎么进行计算的。这里详解一下gcc。 gcc算法&#xff0c;主要涉及到&#xff1a; 拥塞控制的关键信息和公式 卡曼滤波算法 gcc如何使用卡曼滤…...

Linux多进程和多线程(七)进程间通信-信号量

进程间通信之信号量 资源竞争 多个进程竞争同一资源时&#xff0c;会发生资源竞争。 资源竞争会导致进程的执行出现不可预测的结果。 临界资源 不允许同时有多个进程访问的资源, 包括硬件资源 (CPU、内存、存储器以及其他外 围设备) 与软件资源(共享代码段、共享数据结构) …...

Qwen3-Reranker-0.6B一文详解:轻量0.6B参数如何实现SOTA级重排序性能

Qwen3-Reranker-0.6B一文详解&#xff1a;轻量0.6B参数如何实现SOTA级重排序性能 1. 引言&#xff1a;为什么你需要关注这个0.6B的小模型&#xff1f; 如果你用过搜索引擎&#xff0c;肯定有过这样的体验&#xff1a;输入一个问题&#xff0c;搜出来一堆结果&#xff0c;但真…...

STM32F103红外小车避坑指南:从Proteus仿真失败到实物调试成功

STM32F103红外小车避坑指南&#xff1a;从Proteus仿真失败到实物调试成功 第一次尝试用STM32F103做红外循迹小车时&#xff0c;我花了整整三天时间在Proteus里调试仿真&#xff0c;结果连最基本的电机转动都实现不了。直到把电路搬到实物上&#xff0c;才发现仿真环境里那些看似…...

厦门选117E还是120E?手把手教你为你的城市选择正确的高斯克吕格投影坐标系

厦门GIS项目实战&#xff1a;如何精准选择高斯克吕格投影坐标系 第一次在ArcGIS里看到上百个坐标系选项时&#xff0c;我的鼠标指针在列表上方徘徊了整整十五分钟——就像站在自动售货机前不知道按哪个按钮的新手。特别是当项目 deadline 临近&#xff0c;而厦门市规划局的Shap…...

CodeMaker:让编码效率提升3倍的智能代码生成工具

CodeMaker&#xff1a;让编码效率提升3倍的智能代码生成工具 【免费下载链接】CodeMaker A idea-plugin for Java/Scala, support custom code template. 项目地址: https://gitcode.com/gh_mirrors/co/CodeMaker 一、核心价值&#xff1a;重新定义开发效率 你是否也曾…...

Bilibili-Evolved性能优化实战:突破60fps流畅播放全解析

Bilibili-Evolved性能优化实战&#xff1a;突破60fps流畅播放全解析 【免费下载链接】Bilibili-Evolved 强大的哔哩哔哩增强脚本 项目地址: https://gitcode.com/gh_mirrors/bi/Bilibili-Evolved Bilibili-Evolved作为强大的哔哩哔哩增强脚本&#xff0c;通过深度优化浏…...

小米智能家居与Home Assistant完美融合:打造高效智能家居生态

小米智能家居与Home Assistant完美融合&#xff1a;打造高效智能家居生态 【免费下载链接】ha_xiaomi_home Xiaomi Home Integration for Home Assistant 项目地址: https://gitcode.com/GitHub_Trending/ha/ha_xiaomi_home 小米智能家居Home Assistant集成是由小米官方…...

从产品质量到A/B测试:聊聊高斯分布在真实业务场景中的10个应用与常见误区

高斯分布实战手册&#xff1a;10个业务场景中的智能决策与避坑指南 当你发现某电商平台上的用户购买金额呈现"中间多、两头少"的分布时&#xff0c;当A/B测试结果出现微妙的5%转化率差异时&#xff0c;当工厂质检数据出现异常波动时——这些看似无关的业务问题背后&a…...

从手机端到边缘设备:聊聊轻量化模型设计中FLOPs、MACs和Params的权衡艺术

从手机端到边缘设备&#xff1a;轻量化模型设计中FLOPs、MACs和Params的权衡艺术 当我们在智能手机上使用人脸解锁功能&#xff0c;或是通过智能音箱与AI助手对话时&#xff0c;背后运行的往往是经过精心设计的轻量化神经网络模型。这些模型需要在有限的算力和内存资源下&#…...

揭秘Figma-MCP与ClaudeCode:驱动像素级UI还原的协议与智能引擎

1. Figma-MCP协议&#xff1a;设计到代码的桥梁 Figma-MCP协议是连接设计工具与开发环境的关键纽带。我第一次接触这个协议时&#xff0c;就被它解决设计还原痛点的能力震撼了。传统开发流程中&#xff0c;设计师在Figma里精心打磨的界面&#xff0c;到了开发阶段往往要经历痛苦…...

旧iOS设备维护全流程解决方案:Legacy iOS Kit实用指南

旧iOS设备维护全流程解决方案&#xff1a;Legacy iOS Kit实用指南 【免费下载链接】Legacy-iOS-Kit An all-in-one tool to downgrade/restore, save SHSH blobs, and jailbreak legacy iOS devices 项目地址: https://gitcode.com/gh_mirrors/le/Legacy-iOS-Kit Legacy…...