【Qt/C++】深入理解 Lambda 表达式与 `mutable` 关键字的使用

【Qt/C++】深入理解 Lambda 表达式与 mutable 关键字的使用

在 Qt 开发中,我们常常会用到 lambda 表达式来编写简洁的槽函数。今天通过一个实际代码示例,详细讲解 lambda 的语法、变量捕获方式,特别是 mutable 的作用。

示例代码

QPushButton * myBtn = new QPushButton(this);
QPushButton * myBtn2 = new QPushButton(this);
myBtn2->move(100, 100);
int m = 10;connect(myBtn, &QPushButton::clicked, this, [m]() mutable {m = 100 + 10;qDebug() << m;
});connect(myBtn2, &QPushButton::clicked, this, [=]() {qDebug() << m;
});qDebug() << m;

一、Lambda 表达式基本结构

Lambda 表达式的完整语法如下:

[capture](parameter_list) mutable -> return_type {// function body
};

每个部分含义如下:

  • [capture]:捕获列表,决定 lambda 能访问哪些外部变量以及如何访问;
  • (parameter_list):传入 lambda 的参数;
  • mutable(可选):允许修改捕获的变量副本;
  • -> return_type(可选):指定返回类型;
  • { ... }:函数体。

二、示例中的捕获方式说明

connect(myBtn, ..., [m]() mutable {...})

  • [m] 表示 按值捕获 变量 m。lambda 拿到的是 m 的拷贝;
  • mutable 关键字允许修改这个拷贝,否则按值捕获的变量在 lambda 中默认是 const 的;
  • 这段代码中,m = 100 + 10; 是合法的,因为 mutable 去除了 m 的只读限制;
  • 需要注意,这种修改只作用在拷贝上,不影响外部的 m

connect(myBtn2, ..., [=]() {...})

  • [=] 表示 按值捕获所有外部变量
  • 没有加 mutable,所以 lambda 内部对 m 是只读的;
  • qDebug() << m; 打印的是外部 m 的原始值,即 10

三、mutable 的关键作用

默认情况下,按值捕获的变量在 lambda 中是 const 的:

int x = 5;
auto func = [x]() {x = 10; // 编译错误!x 是 const
};

加上 mutable 后就允许修改:

int x = 5;
auto func = [x]() mutable {x = 10; // 合法,修改的是 x 的副本
};

这在一些涉及临时变量处理的场景中非常有用,尤其是在 Qt 信号槽连接中修改状态时。

四、输出结果分析

假设用户点击了 myBtnmyBtn2

  1. qDebug() << m; 最初输出 10

  2. 点击 myBtn

    • 输出 110,是 lambda 拷贝的 m 被修改;
  3. 点击 myBtn2

    • 输出 10,lambda 看到的仍是最初的 m 值,因为它是按值捕获的;
    • 没有使用 mutable,无法修改。

五、最佳实践建议

  • 若只需要读取变量,推荐用 [=] 捕获;
  • 若要修改变量拷贝,用 [x] mutable
  • 若想修改外部变量本体,使用 引用捕获 [&x]
  • 警惕 [&] 捕获所有变量引用,虽然方便但易引发生命周期错误。

总结

捕获方式说明可修改?是否影响外部变量
[m]按值捕获变量 m❌ 默认不可以
✅ 使用 mutable
❌ 不影响
[=]按值捕获所有变量
[&m]引用捕获变量 m
[&]引用捕获所有变量

通过这个例子,希望你能对 lambda 表达式的使用和 mutable 关键字有更深入的理解,特别是在 Qt 的信号槽连接中,lambda 是一种高效优雅的解决方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/82544.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录 ubuntu 安装中文语言出现 software database is broken

搜索出来的结果是 sudo apt-get install language-pack-zh-han* 然而,无效,最后手动安装如下 apt install language-pack-zh-hans apt install language-pack-zh-hans-base apt install language-pack-gnome-zh-hans apt install fonts-arphic-uming apt install libreoffic…

[虚幻官方教程学习笔记]深入理解实时渲染(An In-Depth Look at Real-Time Rendering)

原英文教程地址深入理解实时渲染&#xff08;An In-Depth Look at Real-Time Rendering&#xff09; 文章目录 1.Intro to An In-Depth Look at Real-Time RenderingCPU VS GPUDeferred VS Forward 2. Before Rendering and OcclusionCulling计算的步骤使用console command:fre…

Linux进程间信号

目录 信号入门 生活角度中的信号 技术应用角度的信号 信号的发送与记录 信号处理常见方式概述 产生信号 通过终端按键产生 通过系统函数向进程发信号 由软件条件产生信号 由硬件异常产生信号 阻塞信号 信号其他相关常见概念 在内核中的表示 sigset_t 信号集操作…

Git简介和发展

Git 简介 Git是一个开源的分布式版本控制系统&#xff0c;跨平台&#xff0c;支持Windows、Linux、MacOS。主要是用于项目的版本管理&#xff0c;是由林纳斯托瓦兹(Linux Torvalds)在2005年为Linux内核开发而创建。 起因 在2002年至2005年间&#xff0c;Linux内核开发团队使…

Perspective,数据可视化的超级引擎!

Perspective 是一个强大的交互式数据分析和可视化库&#xff0c;它允许你创建高度可配置的报告、仪表板、笔记本和应用程序。给用户提供了一个新的视角来看待数据。 Stars 数9125Forks 数1217 主要特点 高效流式查询引擎&#xff1a;Perspective使用C编写&#xff0c;并编译为…

MySQL COUNT(*) 查询优化详解!

目录 前言1. COUNT(*) 为什么慢&#xff1f;—— InnoDB 的“计数烦恼” &#x1f914;2. MySQL 执行 COUNT(*) 的方式 (InnoDB)3. COUNT(*) 优化策略&#xff1a;快&#xff01;准&#xff01;狠&#xff01;策略一&#xff1a;利用索引优化带 WHERE 子句的 COUNT(*) (最常见且…

如何在postman使用时间戳

1. 使用 Pre-request Script 动态转换​ 在发送请求前&#xff0c;将日期字符串转为时间戳并存储为环境变量/全局变量。 ​示例代码​ // 将日期字符串&#xff08;如 "2023-10-01"&#xff09;转为时间戳&#xff08;毫秒&#xff09; const dateString "2…

嵌入式学习笔记 - 运算放大器的共模抑制比

一 定义 共模抑制比&#xff08;Common Mode Rejection Ratio, ‌CMRR‌&#xff09;是衡量差分放大器&#xff08;或差分电路&#xff09;抑制共模信号能力的关键指标。它在电子工程中尤为重要&#xff0c;特别是在需要处理微弱信号或对抗环境噪声的场景中。 核心概念 ‌共…

成龙电影中的三菱汽车

帕杰罗、 Lancer Evolution、 3000GT Mitsubishi Lancer Evo ll 1995 附录 Mercedes-Benz 280SL&#xff08;W113&#xff09;&#xff0c;俗称“Pagoda”&#xff08;帕格达&#xff09;

Spring 项目无法连接 MySQL:Nacos 配置误区排查与解决

在开发过程中&#xff0c;我们使用 Nacos 来管理 Spring Boot 项目的配置&#xff0c;其中包括数据库连接配置。然而&#xff0c;在实际操作中&#xff0c;由于一些概念的混淆&#xff0c;我们遇到了一些连接问题。本文将分享我的故障排查过程&#xff0c;帮助大家避免类似的错…

LabVIEW与 IMAQ Vision 机器视觉应用

在工业生产及诸多领域&#xff0c;精确高效的检测至关重要。基于 LabVIEW 与 IMAQ Vision 的机器视觉应用&#xff0c;深入剖析其原理、系统构成、软件设计及优势&#xff0c;为相关领域工程师提供全面技术参考。 ​ 一、技术原理 &#xff08;一&#xff09;机器视觉技术基础…

【STM32 学习笔记】USART串口

注意&#xff1a;在串口助手的接收模式中有文本模式和HEX模式两种模式&#xff0c;那么它们有什么区别&#xff1f;   文本模式和Hex模式是两种不同的文件编辑或浏览模式&#xff0c;不是完全相同的概念。文本模式通常是指以ASCII编码格式表示文本文件的编辑或浏览模式。在文…

【WPS】怎么解决“word的复制表格”粘贴到“excel的单元格”变多行单元格的问题

把 word文档复制表格到这个excel表格上面的话&#xff0c;会出现由单个单元格变成多行单元格的情况。 现在&#xff0c;就这个问题怎么解决&#xff0c;提出了一个方案&#xff0c;就是先查找是什么导致了这个换行&#xff0c;然后再将换行的这个字符进行一个整体的替换&#x…

嵌入式开发面试题详解:STM32 与嵌入式开发核心知识全面解析

一、STM32 共有几种基本时钟信号&#xff1f; 题目 STM32 共有几种基本时钟信号&#xff1f; 解答 STM32 包含 4 种基本时钟信号&#xff0c;分别为 HSI&#xff08;内部高速时钟&#xff09;、HSE&#xff08;外部高速时钟&#xff09;、LSI&#xff08;内部低速时钟&…

华为策略路由

路由策略&#xff1a;是对路由条目进行控制&#xff0c;通告控制路由条目影响报文的转发路径。路由策略为控制平面。 策略路由&#xff1a;是根据报文特征&#xff0c;认为的控制报文从某个即可转发出去&#xff0c;不修改路由表。即策略路由为在转发平面。 路由策略 策略路由…

# YOLOv3:深度学习中的目标检测利器

YOLOv3&#xff1a;深度学习中的目标检测利器 引言 在计算机视觉领域&#xff0c;目标检测是一项核心任务&#xff0c;它涉及到识别图像或视频中的物体&#xff0c;并确定它们的位置。随着深度学习技术的快速发展&#xff0c;目标检测算法也在不断进步。YOLO&#xff08;You …

红黑树删除的实现与四种情况的证明

&#x1f9ed; 学习重点 删除节点的三种情况红黑树如何恢复性质四种修复情况完整可运行的 C 实现 一、红黑树删除的基础理解 红黑树删除比插入复杂得多&#xff0c;因为&#xff1a; 删除的是黑节点可能会破坏“从根到叶子黑节点数相等”的性质。删除红节点无需修复&#xf…

vue配置代理解决前端跨域的问题

文章目录 一、概述二、报错现象三、通过配置代理来解决修改request.js中的baseURL为/api在vite.config.js中增加代理配置 四、参考资料 一、概述 跨域是指由于浏览器的同源策略限制&#xff0c;向不同源(不同协议、不同域名、不同端口)发送ajax请求会失败 二、报错现象 三、…

T-SQL在SQL Server中判断表、字段、索引、视图、触发器、Synonym等是否存在

SQL Server创建或者删除表、字段、索引、视图、触发器前判断是否存在。 目录 1. SQL Server创建表之前判断表是否存在 2. SQL Server新增字段之前判断是否存在 3. SQL Server删除字段之前判断是否存在 4. SQL Server新增索引之前判断是否存在 5. SQL Server判断视图是否存…

金融企业如何借力运维监控强化合规性建设?

日前&#xff0c;国家金融监督管理总局网站公布行政处罚信息&#xff0c;认定某银行存在多项违规并对其进行罚款。其中&#xff0c;国家金融监督管理总局认定该银行主要违规内容包括&#xff1a; 一、部分重要信息系统识别不全面&#xff0c;灾备建设和灾难恢复能力不符合监管要…