[Deepseek 学c++]初始化捕获与按值(显式与隐式)捕获傻傻分不清

embedded/2025/3/26 9:58:17/

之前effective Modern C++ 条款31 看了几次似懂非懂,现在终于理解了这一章。

1. 静态变量可以在lambda 表达式使用,但不能被捕获

考虑以下这道题:
在这里插入图片描述
初始化捕获和默认值捕获的结果 a 值是什么? deepseek 第二个给的答案是错的。
在这里插入图片描述
注意静态变量,与引用传递和值传递无关, 只能捕获非静态局部变量。effective 里说的
以上说法不对。

        static int y = 20;auto f = [y = y]() mutable { ++y; };f(); return y; 输出20static int y = 20;auto f = [=]() mutable { ++y; };f(); return y; y 为21
不捕获static int y = 20;auto f = []() mutable { ++y; };f(); return y;  输出21static int y = 20;auto f = [&]() mutable { ++y; };f(); return y; 21static int y = 20;auto f = [&y = y]() mutable { ++y; };f(); return y; 21

[&a = a]: by-reference capture with an initializer
相当于在lambda函数体中加了一个新的变量auto &a, 其初值为函数作用域内的 static int a;引用,对新的a操作实际还是修改的是static int a
[a = a]:by-copy capture with an initializer
相当于 lambda函数体中加了一个新的变量 auto a, 其初值为外部的 static int a;操作是新的a

        int y = 20;auto f = [y = y]() mutable { ++y; };f(); return y; 20int y = 20;auto f = [=]() mutable { ++y; };f(); return y; 20

闭包与闭包类

闭包通常指的是函数对象,也就是lambda表达式生成的对象,而闭包类可能是指实现闭包的底层类结构。不过,用户可能对这两个术语的具体区别不太清楚,需要详细解释。

首先,回忆一下C++中的lambda表达式。当写一个lambda时,编译器会生成一个匿名的函数对象类,这个类通常被称为闭包类。而闭包则是这个类的实例,也就是具体的对象。因此,闭包类是类型,而闭包是该类型的对象。用户可能混淆了这两个概念,需要指出它们的层次不同。

接下来,需要详细说明闭包类的结构。比如,lambda捕获的变量会成为闭包类的成员变量,operator()的重载实现函数调用。而闭包则是这个类的一个实例,包含了具体的捕获值。例如,当使用不同的捕获方式(如值捕获、引用捕获)时,闭包类的成员变量类型和存储方式也会不同
闭包类是类型,闭包是实例;**闭包类由编译器生成,包含数据成员和operator(),而闭包是该类的具体对象,持有捕获的变量。**确保用户能够清晰区分这两个概念,并在实际编程中正确使用lambda和理解其底层机制。

2. 为什么需要初始化捕获

对类成员变量的 捕获
输出y 是20, 为什么?

class Solution {
private:// int y = 20;
public:int y = 20;int findMaxForm(vector<string>& strs, int m, int n) {auto f = [=]() mutable { ++y; };f(); cout << "y:" << y << endl;return 0;}
}; 输出y 是21, 为什么?

当lambda在类成员函数内部捕获成员变量时,直接使用成员变量名可能不会像普通局部变量那样被捕获。因为成员变量实际上是通过this指针访问的,所以当使用[=]捕获时,实际上会隐式捕获this指针,而不是直接捕获成员变量y。也就是说,lambda中的y实际上是通过this指针访问的类成员变量,而不是一个副本。

而输出y 是20, 为什么?

class Solution {
public:int findMaxForm(vector<string>& strs, int m, int n) {int y = 20;auto f = [=]() mutable { ++y; };f(); cout << "y:" << y << endl;return 0;}
}; 

解释,第一种相当于隐式捕获this指针, 即代码等价于

在这里插入图片描述

什么都不加报错

在这里插入图片描述
在这里插入图片描述

auto f = y = y mutable { ++y; }; 与 [y] 的区别

前者正常通过编译,。
在这里插入图片描述

effective 提到, 按引用或值捕获的变量必须 是lambda 表达式作用域可见的 非静态局部变量, 不能是成员变量。(初始化捕获,即广义捕获除外)
在这里插入图片描述
在这里插入图片描述

初始化捕获、按值捕获,区别

在这里插入图片描述
在这里插入图片描述在这里插入图片描述


http://www.ppmy.cn/embedded/176252.html

相关文章

时序数据库QuestDB在Winform窗体应用

以下是QuestDB在Winform使用的代码&#xff1a; //初始化 private void Init() { //创建数据库对象 (用法和EF Dappper一样通过new保证线程安全) SqlSugarClient Db new SqlSugarClient(new ConnectionConfig() { ConnectionString “host10.3.5.227;port8812;usernameadmin;…

HTTP/HTTPS 中 GET 请求和 POST 请求的区别与联系

一、基础概念 HTTP (HyperText Transfer Protocol, 超文本传输协议) 是一种用于浏览器与服务器之间进行数据交互的协议。HTTPS (加密的 HTTP) 则通过 SSL/TLS 协议实现通信加密与数据安全性。 二、GET 和 POST 概述 GET 请求: 用于从服务器获取资源。 POST 请求: 用于将数据…

用selenium+ChromeDriver豆瓣电影 肖申克的救赎 短评爬取(pycharm 爬虫)

一、豆瓣电影 肖申克的救赎 短评url=https://movie.douban.com/subject/1292052/comments 二、基本知识点讲解 1. Selenium 的基本使用 Selenium 是一个用于自动化浏览器操作的库,常用于网页测试和爬虫。代码中使用了以下 Selenium 的核心功能: webdriver.Chrome: 启动 Chr…

大模型在非小细胞肺癌预测及治疗方案制定中的应用研究报告

目录 一、引言 1.1 研究背景与意义 1.2 研究目的与创新点 二、大模型预测非小细胞肺癌的原理与方法 2.1 相关大模型介绍 2.2 数据收集与预处理 2.3 特征工程 2.4 模型训练与优化 三、术前风险预测与手术方案制定 3.1 术前风险预测指标 3.2 大模型预测术前风险的效果…

DeepSeek写打台球手机小游戏

DeepSeek写打台球手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端打台球小游戏H5文件&#xff1a; 要求 可以重新开始游戏 可以暂停游戏 有白球和其他颜色的球&am…

机器人的手眼标定——机器人抓取系统基础系列(五)

机器人的手眼标定——机器人抓取系统基础系列&#xff08;五&#xff09; 前言一、机器人标定相关概念1.1 内参标定和外参标定1.2 Eye-in-Hand 和 Eye-to-Hand1.3 ArUco二维码和棋盘格标定区别 二、机器人标定基本原理2.1 机器人抓取系统坐标系2.2 标定原理 三、标定步骤和注意…

课外活动:怎么理解可变成本?

可变成本深度解析 &#x1f9ee; 一、可变成本的本质 #mermaid-svg-qoqQaFxQBuZZfAD2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qoqQaFxQBuZZfAD2 .error-icon{fill:#552222;}#mermaid-svg-qoqQaFxQBuZZfAD2 …

自然语言处理(5)—— 中文分词

中文分词的基本原理及实现 1. 什么是词2. 基本原理3. 发展趋势&#xff1a;多数场景无需显式分词 信息处理的目标是使用计算机能够理解和产生自然语言。而自然语言理解和产生的前提是对语言能够做出全面的解析。 汉语词汇是语言中能够独立运用的最小的语言单位&#xff0c;是语…