C++lambda表达式

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

C++ 的 lambda 表达式 是一种简洁的方式,用于定义匿名函数或可调用对象。它通常用于需要短小、内联定义的函数,尤其适用于 STL 算法、并行编程、事件处理等场景。Lambda 表达式的语法灵活且强大,可以捕获外部变量、指定参数类型、返回值类型等。

1. Lambda 表达式的基本语法:

[捕获列表](参数列表) -> 返回类型 { 函数体 }
  • 捕获列表 [ ]:指定 Lambda 表达式如何捕获外部变量。可以通过值捕获(复制外部变量)或者引用捕获(直接引用外部变量)等方式。
  • 参数列表 ( ):指定函数的输入参数。
  • 返回类型 ->:指定 Lambda 表达式的返回类型,通常情况下,C++ 可以自动推导返回类型,因此可以省略 -> 部分。如果需要,可以显式指定返回类型。
  • 函数体 { }:Lambda 表达式的代码块,执行实际的操作。

2. 捕获外部变量(捕获列表)

Lambda 表达式可以捕获外部作用域中的变量(即定义在 Lambda 外部的变量),这使得 Lambda 能够在局部环境中使用这些外部变量。

  • 按值捕获:[x] 复制外部变量 x 的值到 Lambda 中。
  • 按引用捕获:[&] 按引用捕获所有外部变量,使得 Lambda 内部能够修改外部变量。
  • 混合捕获:可以同时按值和按引用捕获不同的变量,例如 [x, &y] 表示按值捕获 x,按引用捕获 y。
  • 捕获 this 指针:[this] 可以捕获当前对象的 this 指针,用于在 Lambda 表达式中访问类的成员变量或成员函数。

3. 示例代码

3.1 基本 Lambda 表达式
#include <iostream>
using namespace std;

int main() {
    // 一个不带捕获的 Lambda,接受两个整数参数并返回它们的和
    auto add = [](int a, int b) -> int {
        return a + b;
    };

    cout << "Sum: " << add(3, 5) << endl;  // 输出: Sum: 8
    return 0;
}
3.2 捕获外部变量
#include <iostream>
using namespace std;

int main() {
    int x = 10, y = 20;
    
    // 按值捕获 x 和按引用捕获 y
    auto lambda = [x, &y]() {
        cout << "Captured by value: " << x << endl;  // x 的值是 10
        cout << "Captured by reference: " << y << endl;  // y 的值是 20
        y += 5;  // 修改 y 的值
    };

    lambda();
    cout << "After lambda, y = " << y << endl;  // 输出: After lambda, y = 25
    return 0;
}
  • 在上面的例子中,x 按值捕获,而 y 按引用捕获。调用 Lambda 后,y 的值被修改,而 x 的值保持不变。
3.3 捕获 this 指针(在类成员函数中使用)
#include <iostream>
using namespace std;

class MyClass {
public:
    MyClass(int val) : value(val) {}

    void print() {
        // 捕获 this 指针
        auto lambda = [this]() {
            cout << "Value from class: " << value << endl;
        };
        lambda();
    }

private:
    int value;
};

int main() {
    MyClass obj(42);
    obj.print();  // 输出: Value from class: 42
    return 0;
}
  • 在上面的代码中,Lambda 表达式通过捕获 this 指针访问类的成员变量 value。捕获 this 使得 Lambda 可以访问当前对象的成员。
3.4 返回类型推导与显式返回类型
  • 自动推导返回类型:Lambda 表达式可以省略返回类型,C++ 会自动推导。
  • 显式指定返回类型:可以通过 -> 语法显式指定 Lambda 的返回类型。
#include <iostream>
using namespace std;

int main() {
    // 自动推导返回类型
    auto multiply = [](int a, int b) {
        return a * b;
    };
    cout << "Product: " << multiply(3, 4) << endl;  // 输出: Product: 12

    // 显式指定返回类型
    auto divide = [](int a, int b) -> double {
        return static_cast<double>(a) / b;
    };
    cout << "Division: " << divide(5, 2) << endl;  // 输出: Division: 2.5

    return 0;
}
  • 第一个 multiply Lambda 没有显式返回类型,编译器根据 a * b 的类型自动推导出返回值为 int。
  • 第二个 divide Lambda 显式指定了返回类型为 double,即使 a 和 b 是 int 类型,返回值类型也是 double。

4. Lambda 表达式的应用场景

  • STL 算法:很多 STL 算法(如 std::for_each, std::sort, std::transform 等)都可以接受 Lambda 表达式作为参数,用于指定如何处理集合中的元素。

    示例:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    
    int main() {
        vector<int> vec = {1, 2, 3, 4, 5};
    
        // 使用 Lambda 表达式打印每个元素
        for_each(vec.begin(), vec.end(), [](int x) {
            cout << x << " ";
        });
    
        cout << endl;
        return 0;
    }
    

  • 事件处理和回调函数:Lambda 表达式可以用作回调函数(如 GUI 程序中的事件处理、并发编程中的线程回调等)。

  • 并行编程:在并行编程中,Lambda 使得任务划分和分配变得简单和直观。

    #include <iostream>
    #include <thread>
    
    using namespace std;
    
    int main() {
        // 使用 Lambda 创建一个新线程
        thread t([]() {
            cout << "Hello from thread!" << endl;
        });
    
        t.join();  // 等待线程结束
        return 0;
    }
    

    Lambda是如何捕获的?

C++ 中,Lambda 捕获外部变量是基于作用域,而不是类型或最近距离。捕获变量是按照 作用域(即变量定义的范围)来决定的,而不是基于变量类型或物理位置的距离。

关键点:

  • Lambda 捕获变量是基于外部作用域中可访问的变量。
  • 如果捕获的变量与 Lambda 作用域内的其他变量同名,Lambda 会捕获 最外层作用域 中的变量,而不是局部作用域的同名变量。
  • Lambda 捕获是 静态的,即在编译时确定,而不是动态判断的。
#include <iostream>

void example() {
    int x = 10;  // 局部变量 x

    // Lambda 捕获外部变量 x
    auto lambda1 = [x]() {  // 捕获外部 x
        std::cout << "lambda1 captured x (by value): " << x << std::endl;
    };

    {
        int x = 20;  // 内部作用域中的局部变量 x

        // Lambda 捕获外部 x
        auto lambda2 = [x]() {  // 捕获外部 x
            std::cout << "lambda2 captured x (by value): " << x << std::endl;
        };

        lambda1();  // 输出 lambda1 捕获的外部作用域的 x
        lambda2();  // 输出 lambda2 捕获的内部作用域的 x
    }

    // 内部作用域结束,lambda2 销毁
    lambda1();  // 输出 lambda1 捕获的外部作用域的 x
}

int main() {
    example();
    return 0;
}
  1. lambda1 捕获的是函数外层作用域的 x(值为 10)。
  2. lambda2 在内层作用域中定义,它捕获的是内层作用域中的 x(值为 20)。尽管在 lambda2 定义时,外层作用域的 x 仍然是存在的,Lambda 会捕获其定义时作用域中的 x。这证明了捕获变量是基于作用域,而不是距离或类型。

进一步解释:

  • 作用域规则:lambda1 捕获的是外层作用域中的 x(值 10),而 lambda2 捕获的是它定义时的内层作用域中的 x(值 20)。
  • 捕获规则:Lambda 在定义时,根据它的作用域来决定捕获什么变量。捕获的变量不是基于类型或物理距离,而是 基于编译时的作用域。

如果外部作用域有多个变量,Lambda 可以通过捕获列表显式指定需要捕获哪些变量。捕获列表允许你选择性地捕获特定的变量,并且可以按值或按引用捕获。

#include <iostream>

void example() {
    int a = 10, b = 20;

    // 捕获 a 按值,b 按引用
    auto lambda = [a, &b]() {
        std::cout << "Captured a by value: " << a << std::endl;
        std::cout << "Captured b by reference: " << b << std::endl;
        b += 10;  // 修改 b
    };

    lambda();

    // 输出修改后的 b
    std::cout << "After lambda, b = " << b << std::endl;
}

int main() {
    example();
    return 0;
}

​C++ 中的 Lambda​ C++11引入了lambda表达式,使得C++程序员能够编写更简洁的回调函数和闭包,表达式用于定义并创建匿名的函数对象,以简化编程工作。 阅读详情

相关推荐

C++ Lambda表达式

C++ Lambda表达式是C++11引入的匿名函数特性,允许内联定义小型函数。其基本语法包含捕获列表、参数列表、返回类型和函数体。捕获列表支持按值或引用访问外部变量。示例展示了Lambda的多种用法:作为加法函数、匿名比较函数以及与捕获机制结合使用。文章还对比了Lambda函数与内联函数的区别,指出Lambda的优势在于匿名性和变量捕获能力,而内联函数侧重性能优化。Lambda适用于一次性场景如回调函数,使代码更简洁直接。

weixin_54859557的博客 768

C ++ Lambda表达式详解

C ++ Lambda表达式详解 1.Lambda表达式概述 ​ Lambda表达式是现代C++在C ++ 11和更高版本中的一个新的语法糖 ,在C++11、C++14、C++17和C++20中Lambda表达的内容还在不断更新。 lambda表达式(也称为lambda函数)是在调用或作为函数参数传递的位置处定义匿名函数对象的便捷方法。通常,lambda用于封装传递给算法或异步方法的几行代码 。本文主要介绍Lambda的工作原理以及使用方法。 2.Lambda表达式定义 2.1 Lambda表达式示例 ​

白云之道 6万+

C++11 Lambda表达式

Lambda表达式 C++11的一大特性就是引入了Lambda表达式,并在后续的C++14进行了加强。利用Lambda表达式,可以方便定义和创建匿名函数,一个Lambda表达式表示一个可调用单元,我们可以将其理解为一个未命名的内联函数。 Lambda语法定义 [capture list] (paramters list) mutable exception-&amp;amp;gt; return type{fun...

大山喵写博客的地方 2367

c++ lambda

而一个使用了成员变量的类的 operator(),如果能直接被转换为普通的函数指针,那么 lambda 表达式本身的 this 指针就丢失掉了。但是函数内部想修改这变量,但是又不想影响lambda表达式外面的值的时候,就直接添加mutable属性,这样调用lambda表达式的时候,会像函数传递参数一样,在内部定义一个变量并拷贝这个值。如果用[this]、[=]或[&]捕获了,那么线程将运行未定义的行为,因为在传递给线程的lambda中打印name时,lambda将使用已销毁对象的成员。

Ken的博客 3802

一文读懂C++中的Lambda函数:简洁、高效、灵活

一、匿名函数的基本语法; 二、捕获列表: 2.1、值捕获, 2.2、引用捕获, 2.3、隐式捕获, 2.4、空捕获列表, 2.5、表达式捕获, 2.6、泛型 Lambda, 2.7、可变lambda, 2.8、混合捕获, 2.10、Lambda捕获列表总结。 lambda表达式的目的是把函数写的更加内聚;只需要在内部使用,就没必要写到外部,干扰其他函数,同时使代码更简洁。 如果捕获列表为[&],则表示所有的外部变量都按引用传递给lambda使用。

Lion_Long的博客 1万+

告别裸奔MCU!手把手教你用MCP2515+STM32搭建稳定CAN总线通信(附完整代码)

本文详细介绍了如何使用MCP2515与STM32搭建稳定可靠的CAN总线通信系统,适用于汽车电子和工业控制领域。通过硬件架构设计、驱动层实现、数据收发实战及故障排查手册,帮助开发者快速掌握CAN通信技术,提升系统稳定性和开发效率。

weixin_28703489的博客 208

Cpp || lambda 表达式

lambda表达式的使用注意方式

Template Code 2588

Unity FPS射击控制系统:数据驱动的武器行为解耦方案

在Unity第一人称射击(FPS)开发中,射击系统常因输入、状态、行为耦合导致连发异常、换弹冲突与网络同步失准。其本质是缺乏对‘武器行为’(如后坐力曲线、弹药逻辑)与‘射击控制’(如输入合法性校验、冷却调度)的正交分离。本方案基于ScriptableObject实现WeaponData数据资产化,配合ShootingController状态机服务,达成输入解耦、运行时参数可调、协程受控、网络预测友好等工程目标。适用于中大型FPS项目架构升级与数据驱动转型,尤其解决Unity InputSystem与物理反馈

weixin_30536861的博客 609

【C++】Lambda表达式

Lambda表达式是C++11引入的匿名函数对象,具有以下特点: · 就地定义,无需单独命名 · 可捕获上下文变量 · 自动推导返回类型(多数情况) · 可作为函数参数传递

AAADiao的博客 1万+

极验第四代滑块验证码破解(三):滑块轨迹构造

极验第四代滑块验证码破解(三):滑块轨迹构造声明 声明 原创文章,请勿转载! 本文内容仅限于安全研究,不公开具体源码。维护网络安全,人人有责。 本文关联文章超链接:

帯泪的鱼的博客 8624

TI官方PSpice for TI安装避坑指南:从申请Key到解决器件搜索栏空白(附详细步骤)

本文详细介绍了PSpice for TI的安装与配置全流程,包括申请Key、解决器件搜索栏空白等常见问题。通过分步指南和实战避坑技巧,帮助工程师高效完成安装并优化性能,确保电路仿真工具的正常使用。

weixin_29299807的博客 1081

C++11:lambda表达式

lambda表达式是C++11的一个非常重要的一个语法,可以帮助我们简介代码,如果说右值引用是减轻了编译器的负担,那么lambda表达式就是减轻了程序员写代码的负担。

weixin_51142926的博客 2481

STM32F103 串口DMA + 空闲中断 实现不定长数据收发

文章目录1. 空闲中断1.1 uart_dma.c1.2 uart_dma.h1.3 main.c1.4 stm32f10x_it.c1.5 效果演示1.6 知识补充1.6.1 外设的基地址     DMA(Direct Memory Access,直接存储器访问) 是所有现代电脑的重要特色,它允许不同速度的硬件装置来沟通,而不需要依赖于 CPU 的大量中断负载。否则,CPU 需要从来源把每一片段的资料复制到暂存器,然后把它们再次写回到新的地方。在这个时间中,CPU

夏夜晚风_的博客 3万+

【C++】C++11——lambda表达式

C++11——Lambda表达式

weixin_60478154的博客 4544

米哈游 AI产品经理面试题精选:10道高频考题+答案解析(附PDF)

米哈游是全球知名游戏开发商,以《原神》《崩坏》系列著称,专注二次元文化与AI技术创新。本文整理了10道AI产品经理面试题,涵盖Transformer架构、智能NPC设计、机器学习应用、AIGC产品规划等核心领域。题目既考察技术理解(如RAG原理、多模态模型),又关注产品落地(游戏平衡性优化、伦理安全),同时强调跨团队协作能力。参考答案均结合米哈游业务场景,体现技术驱动与玩家体验并重的产品思维,展现AI在游戏行业的创新应用前景。

ZHHHHH15的博客 680

图数据挖掘 ECC K-core core number truss number clique

K-core:什么叫k-core,给定一个正整数k(k>=0),k-core是一个G的最大子图(也就是说k-core是一个图的限制),将这个子图定义为Hk,对于Hk中的每个顶点v,他的度数都是大于等于k的。 k-core是内嵌的,如下图所示,集合{ABCD}是H3,也就是3-core的子图。而集合{ABCDE}是H2,也就是2-core的子图,集合{ABCDEGF}是H1,也就是1-core的子图,而从集合的角度来讲H3<H2<H1。 core number:什么叫kcor

weixin_45193103的博客 1685

C++ 11 Lambda表达式

原文地址:https://www.cnblogs.com/DswCnblog/p/5629165.html C++11的一大亮点就是引入了Lambda表达式。利用Lambda表达式,可以方便的定义和创建匿名函数。对于C++这门语言来说来说,“Lambda表达式”或“匿名函数”这些概念听起来好像很深奥,但很多高级语言在很早以前就已经提供了Lambda表达式的功能,如C#,Python等。今天,我们就...

键盘上狂欢 5223

【ComfyUI专栏】ComfyUI 常用工作流下载与分享网址

首先我们来分享第一个网站,Openart 网站,这个网站同时也能提供比较多的其他类型。但是如果希望下载工作流,我们可以访问到如下的这个站点。作为ComfyUI的学习用户来说,我们通常需要借助他山之石来帮助我们快速成长,因此我们需要找到能够分享和下载的网址。,当前网站是综合性网站,在网站中可以下载各种不同的类型,其中工作流只是可以下载的非常小的部分。这个网站也可以浏览不同的工作流,这个工作流的地址和访问如下的站点。

技术与管理的平衡木- 7792

【C++】lambda 表达式

如果同学们学过其他编程语言(如:Java、python),对 lambda 表达式应该不陌生。lambda 表达式最大的作用就是把一个简单的 类/函数 变为一条语句,可以减少代码量,对程序员友好。本文将对 C++ 中 lambda 表达式的语法进行学习,并简单理解 lambda 表达式的底层。

在这个博客里,我会分享我的技术见解、项目经验和学习笔记,感谢各位支持~ 1054

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

c++中 Lambda表达式

摘要:本文深入解析C++ Lambda表达式优化技巧。关键点包括:1)捕获方式选择,建议明确指定捕获变量而非全捕获;2)值捕获与引用捕获的适用场景及陷阱;3)mutable关键字的作用机制;4)C++14初始化捕获和C++20模板Lambda等新特性。文章指出Lambda实质是编译器生成的匿名类实例,并详细分析生命周期管理、避免悬空引用等常见问题。优化建议包含优先值捕获简单类型、对大型对象使用引用/智能指针、标记const捕获等,强调合理使用Lambda能提升代码性能与可读性。

2401_88413914的博客 1016

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

【C++】Lambda表达式的使用

闭包是指一个函数对象,它包含了函数定义时的环境信息,包括捕获的外部变量。闭包的存在使得lambda函数可以延长外部变量的生命周期,并且可以在函数调用结束后仍然访问这些变量。闭包是一个函数对象,它可以捕获外部作用域中的变量,并在其生命周期内访问和修改这些变量。比如:[=, &a, &b]:以引用传递的方式捕捉变量a和b,值传递方式捕捉其他所有变量 [&,a, this]:值传递方式捕捉变量a和this,引用方式捕捉其他变量。函数对象可以像普通的函数一样被调用,其执行的代码就是lambda表达式中的代码。

AkieMo的博客 2643

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

【C++11】lambda表达式

C++11之lambda表达式。

weixin_63449996的博客 1419

c++ Lambda 表达式

C++ 中的(Lambda Expression)是一种匿名函数,可以在代码中直接定义和使用。Lambda 表达式是 C++11 引入的特性,极大地简化了函数对象的定义和使用,尤其在需要传递简单函数时非常方便。

如履薄冰 1092

cpp lambda表达式

cpp的lambda函数 形如 [](para1,para2){} [&]()->int{}的函数,常用于sort的cmp等

ZnS_oscar的博客 362
上一篇: C++std库
JDPSTC
博客等级 码龄4年 57粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值