QT第八九节课笔记-Lambda表达式

Qt中的lambda表达式 Qt中的lambda表达式 lambda用法超详细讲解 [=]{btn->setText("我的名字叫开机");}; 这是lambda表达式函数的声明,不是调用 QPushButton* btn=new QPushButton("我的名字叫做关机",this); resize(600,400); btn->resize(200,100); //lambda表达式在Qt中应用 [=]{btn->setText("我的名字叫开机");}();// 阅读详情
AI摘要

文章介绍了C++11中Lambda表达式的概念、基本语法,包括捕获外部变量的方式、参数列表和返回类型,以及Lambda在回调函数和临时函数中的应用。同时对比了Lambda与内联函数的区别。

Lambda 表达式是 C++11 引入的一种匿名函数的方式,它允许你在需要函数的地方内联地定义函数,而无需单独命名函数

Lambda 表达式的基本语法如下:

[capture clause](parameters) -> return_type {
    // 函数体
    // 可以使用捕获列表中的变量
    return expression; // 可选的返回语句
}

Lambda 表达式由以下部分组成:

  • 捕获列表(Capture clause):用于捕获外部变量,在 Lambda 表达式中可以访问这些变量。捕获列表可以为空,也可以包含变量列表 [var1, var2, ...]。
  • 参数列表(Parameters):与普通函数的参数列表类似,可以为空或包含参数列表 (param1, param2, ...)。
  • 返回类型(Return type):Lambda 表达式可以自动推断返回类型,也可以显式指定返回类型 -> return_type。如果函数体只有一条返回语句,可以省略返回类型。
  • 函数体(Body):Lambda 表达式的函数体,包含需要执行的代码。

Lambda 表达式最简单的案例是在需要一个小型函数或临时函数时直接使用它。以下是一个非常简单的例子,其中使用 Lambda 表达式来定义一个加法操作,并立即使用它来计算两个数的和。

示例:使用 Lambda 表达式进行加法

#include <iostream>

int main() {
    // 定义一个简单的 Lambda 表达式进行加法
    auto add = [](int a, int b) {
        return a + b;
    };

    // 使用 Lambda 表达式计算两个数的和
    int sum = add(10, 20);

    std::cout << "Sum is: " << sum << std::endl;

    return 0;
}

在这个例子中:

  • 我们定义了一个名为 add 的 Lambda 表达式,它接受两个整数参数,并返回它们的和。
  • 然后,我们使用这个 Lambda 表达式来计算两个数字(10 和 20)的和,并将结果存储在变量 sum 中。
  • 最后,我们打印出这个和。

这个例子展示了 Lambda 表达式的基本用法:作为一种简洁而快速的方式来定义小型函数。

我们可以写一个例子,其中使用一个函数来找出两个数中的较大数,这个函数将接受一个 lambda 函数作为回调来比较这两个数。Lambda 函数将直接在函数调用时定义,完全是匿名的。

先回忆以下回调函数

#include <iostream>

// 函数,接受两个整数和一个比较的 lambda 函数
bool myCompare(int a, int b){
    return a > b;
}

int getMax(int a, int b, bool(*compare)(int, int)) {
    if (compare(a, b)) {
        return a;
    } else {
        return b;
    }
}

int main() {
    int x = 10;
    int y = 20;

    // 回调函数
    int max = getMax(x, y, myCompare);

    std::cout << "The larger number is: " << max << std::endl;

    return 0;
}

示例:使用匿名 Lambda 函数来返回两个数中的较大数

#include <iostream>

// 函数,接受两个整数和一个比较的 lambda 函数
int getMax(int a, int b, bool(*compare)(int, int)) {
    if (compare(a, b)) {
        return a;
    } else {
        return b;
    }
}

int main() {
    int x = 10;
    int y = 20;

    // 直接在函数调用中定义匿名 lambda 函数
    int max = getMax(x, y, [](int a, int b) -> bool {
        return a > b;
    });

    std::cout << "The larger number is: " << max << std::endl;

    return 0;
}

在这个例子中:

  • getMax 函数接受两个整数 a 和 b,以及一个比较函数 compare。这个比较函数是一个指向函数的指针,它接受两个整数并返回一个布尔值。
  • 在 main 函数中,我们调用 getMax,并直接在调用点定义了一个匿名的 lambda 函数。这个 lambda 函数接受两个整数并返回一个表示第一个整数是否大于第二个整数的布尔值。
  • 这个 lambda 函数在 getMax 中被用作比较两个数的逻辑。根据 lambda 函数的返回值,getMax 返回较大的数。

这个例子展示了如何直接在函数调用中使用匿名 lambda 函数,使代码更加简洁和直接。这种方法在需要临时函数逻辑的场合非常有用,尤其是在比较、条件检查或小型回调中。

在 Lambda 表达式中,参数捕获是指 Lambda 表达式从其定义的上下文中捕获变量的能力。这使得 Lambda 可以使用并操作在其外部定义的变量。捕获可以按值(拷贝)或按引用进行。

让我们通过一个简单的示例来展示带参数捕获的 Lambda 表达式。

示例:使用带参数捕获的 Lambda 表达式

#include <iostream>

int main() {
    int x = 10;
    int y = 20;

    // 捕获 x 和 y 以便在 Lambda 内部使用
    // 这里的捕获列表 [x, y] 表示 x 和 y 被按值捕获
    auto sum = [x, y]() {
      //  x++;
      //  y++; 编译器报错,不让修改的
        return x + y;
    };
	
    std::cout << "Sum is: " << sum() << std::endl;
    std::cout << "x is now: " << x << ", y is now: " << y << std::endl;

    // 捕获所有外部变量按值捕获(拷贝)
    int z = 30;
    auto multiply = [=]() {
      //  x++;
      //  y++; 编译器报错,不让修改的
        return x * y * z;
    };
	count << x << "," << y << endl;
    std::cout << "Product is: " << multiply() << std::endl;
	std::cout << "x is now: " << x << ", y is now: " << y << std::endl;
    
    // 捕获所有外部变量按引用捕获
    auto modifyAndSum = [&]() {
        x = 15; // 修改 x 的实际值
        y = 25; // 修改 y 的实际值,允许修改
        return x + y;
    };

    std::cout << "Modified Sum is: " << modifyAndSum() << std::endl;
    std::cout << "x is now: " << x << ", y is now: " << y << std::endl;

    return 0;
}

在这个例子中:

  • 第一个 Lambda 表达式 sum 按值捕获了 x 和 y(即它们的副本)。这意味着 sum 内的 x 和 y 是在 Lambda 定义时的值的拷贝。
  • 第二个 Lambda 表达式 multiply 使用 [=] 捕获列表,这表示它按值捕获所有外部变量。
  • 第三个 Lambda 表达式 modifyAndSum 使用 [&] 捕获列表,这表示它按引用捕获所有外部变量。因此,它可以修改 x 和 y 的原始值。

这个示例展示了如何使用不同类型的捕获列表(按值和按引用)来控制 Lambda 表达式对外部变量的访问和修改。按值捕获是安全的,但不允许修改原始变量,而按引用捕获允许修改原始变量,但需要注意引用的有效性和生命周期问题。

以下是一个表格,概述了 Lambda 函数和内联函数在 C++ 中的相似之处和区别:

特性Lambda 函数内联函数
定义一种匿名函数,通常用于定义在需要它们的地方。一种常规函数,通过 inline 关键字定义。
用途提供一种快捷方式来定义临时的、小型的函数。用于优化小型函数,减少函数调用的开销。
语法使用 [capture](params) { body } 的形式定义。使用常规函数定义语法,但在前面加上 inline 关键字。
生命周期在定义它们的作用域内有效。在整个程序执行期间有效。
捕获外部变量可以捕获外部作用域中的变量(按值或按引用)。不能直接捕获外部变量,只能通过参数传递。
调用方式作为函数对象,可直接调用。像普通函数一样调用。
优化可以被编译器自动内联化,但这取决于编译器优化策略。明确请求编译器尝试内联,但实际内联化也取决于编译器。
可见性通常只在定义它们的局部作用域内可见。可以在定义它的任何作用域内可见。
使用场景适合于一次性使用的场景,如作为回调、在算法中使用等。适合于频繁调用的小型函数。

请注意,虽然 Lambda 函数和内联函数在某些方面有相似之处,如它们都可以被编译器优化以减少调用开销,但它们在设计和用途上有明显的不同。Lambda 函数的核心优势在于它们的匿名性和对外部变量的捕获能力,而内联函数则主要关注于提高小型函数的性能。

【C++】lambda表达式 本篇文章我们要学习的是lambda表达式,它是C++11新增的一种特别方便的语法,相较于之前的函数指针以及仿函数都方便了不少,下面就让我们一起来学习吧。 阅读详情

相关推荐

Qt C++图形界面开发实战:从零构建文档编辑器

图形用户界面(GUI)开发是连接用户与软件功能的核心桥梁,其原理在于通过事件驱动模型响应用户操作。在C++生态中,Qt框架凭借其信号与槽机制、丰富的控件库和跨平台能力,提供了高效构建桌面应用的技术价值。它广泛应用于需要高性能、原生体验的软件,如工业控制、嵌入式界面及专业工具开发。本文聚焦于利用Qt Widgets模块,通过实战一个功能完整的文档编辑器项目,深入讲解界面布局、文件操作(特别是中文路径与UTF-8编码处理)等工程实践,并剖析信号槽连接、资源管理等常见问题,为C++后端快速套用可用界面提供可直接复

weixin_33787529的博客 480

C++ lambda表达式

Lambda表达式是C++11标准引入的一种特性,它提供了一种方便的方式来定义匿名函数。Lambda表达式是一种能够捕捉外部变量并使用它们的函数对象。由捕获列表、参数列表、返回类型和函数体组成;其中,参数列表和返回类型可以忽略,但不可以忽略捕获列表和函数体。[捕获列表](参数列表) -> 返回类型 {函数体}例如:auto f = []{ return 1 + 2;或者 auto f = [](int x, int y)->int{ return x + y;(在后面章节会详细介绍使用规则.)

qq_45604814的博客 7517

C++/Qt开发中cppcheck静态分析工具:原理、集成与实战指南

静态代码分析是软件工程中保障代码质量、预防潜在缺陷的关键技术。其核心原理是在不运行程序的情况下,通过分析源代码的语法结构、控制流和数据流,识别出编码错误、安全漏洞和不良风格。这项技术的核心价值在于能实现缺陷的早期发现,将问题消灭在编码阶段,显著降低后期调试和维护成本,尤其适用于C++这类灵活但易出错的系统级语言。在实际开发中,静态分析工具常被集成到持续集成(CI/CD)流程和代码提交前检查(如Git钩子),为团队协作和自动化质量保障提供支撑。本文以cppcheck这一专注于C/C++的低误报率工具为例,深入

weixin_30414305的博客 447

Qt中使用Lambda表达式

Qt中使用Lambda表达式

m0_73443478的博客 5085

别再为跨线程更新UI发愁了!手把手教你用Qt::invokeMethod搞定(附完整代码示例)

本文详细介绍了Qt框架中跨线程更新UI的终极解决方案——Qt::invokeMethod。通过对比传统方法的局限性,展示了invokeMethod的现代化用法和实战案例,包括基本用法、带返回值调用和多参数传递。文章还提供了文件下载器UI更新的完整代码示例,以及高级技巧与性能优化建议,帮助开发者高效解决跨线程UI操作难题。

weixin_30342209的博客 629

2024最新版C++ Qt实战教程:从零搭建环境到开发桌面应用

C++作为高性能的编程语言,结合Qt框架,为桌面应用开发提供了强大的跨平台解决方案。Qt的信号与槽机制是其核心原理,实现了对象间松耦合的通信,这是理解事件驱动编程的关键。在工程实践中,掌握环境搭建、项目配置和调试技巧,能有效提升开发效率。对于初学者,从Qt Widgets入手,理解.pro文件管理和构建流程,是迈向实际项目开发的重要一步。本教程聚焦于解决新手常见痛点,如环境变量配置、中文乱码调试和独立应用打包,通过实战案例帮助开发者将理论知识转化为工程能力,快速上手C++与Qt的桌面应用开发。

weixin_33812433的博客 325

Qt中lambda表达式的实战技巧与陷阱解析

本文深入解析了在Qt框架中使用lambda表达式的核心技巧与常见陷阱。重点探讨了捕获列表(值传递与引用传递)在信号槽机制中的关键差异,强调了优先使用值传递以确保线程与生命周期安全。同时,文章剖析了mutable关键字的适用场景,并提供了避免悬空指针和利用上下文对象管理连接等进阶安全实践,帮助开发者编写更健壮、高效的Qt代码。

python9snake的博客 169

Qt C++智能指针实战指南:告别内存泄漏与悬空指针

在C++编程中,内存管理是开发者必须面对的核心挑战,尤其涉及动态内存分配时,手动管理极易引发内存泄漏和悬空指针问题。RAII(资源获取即初始化)是一种重要的编程范式,通过将资源生命周期与对象作用域绑定,确保资源自动释放。智能指针技术正是RAII思想的典型实践,它通过封装原始指针并引入所有权语义(如独占所有权、共享所有权),自动化内存管理,显著提升代码安全性与可维护性。在Qt框架开发中,内存管理更具特殊性,需协调C++对象与Qt对象模型。本文聚焦Qt C++开发场景,深入解析QScopedPointer、QS

weixin_33690367的博客 414

QT开发核心库与高频函数实战指南:从基础模块到避坑技巧

在C++跨平台桌面开发领域,信号与槽机制和事件驱动模型是实现组件间松耦合通信的核心原理。这种机制通过元对象系统提供运行时类型信息,极大地提升了代码的可维护性和可扩展性。其技术价值在于将异步编程和界面响应逻辑优雅地结合,为构建复杂交互的图形界面应用提供了坚实基础。在实际工程实践中,开发者需要熟练掌握QT的核心模块,如Qt Core中的字符串处理与容器类、Qt Widgets的界面构建、以及Qt Network的异步通信。本文聚焦于QT常用库与高频函数,系统梳理了QString字符串操作、QList/QMap容

weixin_30410119的博客 373

Qt跨平台开发实战:信号槽、图形视图与性能优化全解析

跨平台应用开发框架是实现一套代码多端运行的核心技术,其核心价值在于提升开发效率、保证应用一致性和降低维护成本。在众多技术方案中,基于C++的框架因其高性能和原生体验而备受青睐。信号与槽机制作为对象间通信的基石,通过发布-订阅模式实现松耦合,结合元对象系统提供类型安全,有效替代了传统的回调函数,是构建复杂交互逻辑的关键。图形视图框架则为数据可视化、绘图软件等复杂交互界面提供了场景、视图、图形项三层架构,通过硬件加速和局部更新策略优化渲染性能。在实际工程中,开发者需关注对象生命周期管理、多线程安全及平台特定代码

weixin_33912453的博客 438

C++从入门到实战:核心语法、内存管理与现代特性全解析

在计算机编程领域,理解底层内存管理和性能优化是构建高效系统的关键。C++作为一门支持底层操作和面向对象编程的语言,其核心原理在于通过直接内存访问和编译器优化实现高性能。这种技术价值使其在游戏引擎、高频交易、嵌入式系统等对性能要求极高的场景中不可替代。本文聚焦C++的核心语法与内存管理,深入探讨智能指针、虚函数表等现代特性,并结合开发环境配置、STL容器使用等工程实践,为学习者提供从基础到进阶的完整路径。通过解析常见面试题和项目实战思路,帮助读者掌握写出健壮、高效C++代码的能力。

weixin_34075268的博客 370

从C到Qt C++开发:面向对象、信号槽与内存管理实战指南

面向对象编程(OOP)是一种将数据和操作封装为对象的编程范式,其核心原理在于通过类实现封装、继承和多态,从而提升代码的复用性和可维护性。这一技术价值在于能够构建更复杂、模块化的软件系统,广泛应用于图形界面开发、游戏引擎和企业级应用等场景。在Qt框架中,OOP与信号槽机制深度结合,实现了类型安全的事件通信,同时智能指针等现代C++特性为内存管理提供了自动化解决方案。本文聚焦于C语言开发者向Qt C++的转型,深入解析面向对象思维、信号槽机制及智能指针等关键概念,帮助读者掌握Qt开发的核心技能。

weixin_34198881的博客 367

C++实战:从零构建中学作业管理系统,详解面向对象与数据库设计

面向对象编程(OOP)是构建复杂软件系统的核心范式,通过封装、继承和多态等特性,将现实世界实体抽象为类,从而提升代码的可维护性和复用性。其原理在于将数据与操作数据的方法绑定,形成高内聚、低耦合的模块。在工程实践中,OOP的价值在于能够清晰地对业务领域进行建模,例如在开发一个家庭作业管理系统时,可以自然地设计出User、Homework等实体类。结合数据库技术,如MySQL,通过合理设计表结构(如建立users、homeworks表并设置外键约束)和运用索引优化,可以实现业务数据的持久化与高效查询。本文以C+

weixin_33770878的博客 410

Qt程序崩溃与隐蔽错误排查:内存管理、多线程与事件循环深度解析

在C++跨平台应用开发中,内存管理和多线程同步是核心基础概念。Qt框架通过对象树机制和信号槽简化了资源管理,但其异步特性也引入了独特的挑战。理解对象生命周期、父子关系及线程安全原理,对于构建稳定应用至关重要。这些机制的技术价值在于提升开发效率,但误用会导致野指针、资源竞争等隐蔽问题。典型应用场景包括桌面GUI、嵌入式界面及工业控制软件。本文聚焦Qt开发中的崩溃排查,针对内存访问违规、多线程交互及事件循环阻塞等高频痛点,提供系统化调试方法,帮助开发者定位深层次错误。

weixin_34226706的博客 792

C++学籍管理系统:从零构建面向对象数据管理应用

面向对象编程(OOP)是软件工程的核心范式,其核心思想是通过类与对象来模拟现实世界,实现代码的封装、继承和多态。在C++实践中,数据持久化是构建实用程序的关键技术,它涉及将内存中的数据通过文件读写或数据库操作进行持久存储,确保程序重启后数据不丢失。掌握这些技术对于开发数据管理类应用具有重要价值,例如学生信息管理、库存系统等。本文以学生学籍管理系统为例,深入探讨如何运用C++的类设计、STL容器和文件流操作,实现一个结构清晰、功能完整的CRUD应用。通过解析环境配置、链表数据结构等常见问题,为初学者提供一个从

weixin_34055787的博客 328

Slint C++菜单栏段错误排查与修复:生命周期管理与内存安全实践

在C++桌面应用开发中,内存安全与对象生命周期管理是保障程序稳定性的核心基础。段错误(Segmentation Fault)作为常见的运行时错误,往往源于悬空指针、无效内存访问等底层问题,尤其在涉及GUI框架与原生代码交互时更为突出。其技术价值在于通过系统化的调试与防御性编程,能够显著提升软件的健壮性与用户体验。在Slint这类声明式UI框架中,菜单栏组件因其动态更新、回调绑定等特性,成为生命周期错配问题的高发区。本文聚焦于**菜单栏**与**段错误**的关联,通过实战案例解析如何利用AddressSani

keke1314520的博客 389

用llama.cpp实战入门C++:Windows下从编译到CUDA加速

C++是一门强调内存控制与系统交互的编程语言,其核心在于理解编译构建、运行时依赖、指针与RAII等底层机制。llama.cpp作为纯C++实现的轻量级大模型推理框架,以约3万行聚焦代码提供了极佳的学习沙盒——它不抽象、不封装,让std::vector、struct、CMakeLists.txt、Visual C++ Redistributable等概念在真实报错与调试中自然浮现。通过在Windows 11下配置VS2022、编译CLI工具、启用CUDA加速及加载qwen3-embedding模型,学习者可同

weixin_30235225的博客 514

Qt--匿名函数Lambda表达式详解

一、简介 C++11中引入了lambda表达式,lambda表达式可以使代码变得简单。C++中,一个lambda表达式表示一个可调用的代码单元。对于一个简单的计算,我们可以通过定义函数的形式,或者使用匿名函数的方法来实现。当然,如果这个函数功能十分简单,不会被重复使用,又不至于单独写一个函数,可以通过匿名函数简化代码。 二、使用说明 2.1、引入C++11 在工程文件(.pro)中引入C++11: 2.2、Lambda表达式语法 [capture](parameters) mutable ->r

贝勒里恩的博客 5257
上一篇: QT视频第四节课笔记-命名空间
下一篇: QT第五六七节课笔记 - 用C语言快速入门
上官可编程
博客等级 码龄14年 1398粉丝 17原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上官可编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值