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

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

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

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

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

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

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

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

        static 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; 20
        
   int 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 表达式作用域可见的 非静态局部变量, 不能是成员变量。(初始化捕获,即广义捕获除外)
在这里插入图片描述
在这里插入图片描述

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

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

相关文章:

  • 2025年云南食品安全员管理员考试题库
  • 代码随想录_动态规划
  • webpack等构建工具如何支持移除未使用的代码
  • 力扣hot100——三数之和(双指针)
  • 每天五分钟玩转深度学习PyTorch:基于pytorch搭建LSTM和GRU模型
  • 深度优先搜索(DFS)与广度优先搜索(BFS)全面解析 + 经典算法题实战(Java实现)
  • leetcode106 从中序与后序遍历序列构造二叉树
  • Java学习笔记-XXH3哈希算法
  • Dify 项目开源大模型应用开发平台
  • deque
  • Linux基础开发工具--gdb的使用
  • 蓝桥杯青少组stema2025年3月9日scratch初级组真题——转动的图形
  • 除自身以外数组的乘积——面试经典150题(力扣)
  • 每天一道算法题-两数相加
  • C++编程语言特性
  • Android Jetpack Compose介绍
  • 238.除自身以外数组的乘积
  • 【sgHelp】自定义组件:网站、平台右下角的帮助助手、指导助理
  • app测试必须进行吗?需要进行哪些测试?
  • 混元视频与万相2.1全面对比分析
  • 江苏省人民检察院副检察长丁海涛调任省委政法委副书记
  • 王毅同丹麦外交大臣拉斯穆森会谈
  • 遭车祸罹难的村医遇“身份”难题:镇卫生院否认劳动关系,家属上诉后二审将开庭
  • 英国6月初将公布对华关系的审计报告,外交部:望英方树立正确政策导向
  • 中国恒大披露清盘进展:要求债权人提交债权证明表
  • 中国进出口银行:1-4月投放制造业中长期贷款超1800亿元