C++中的Lambda表达式

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

C++中有  五种可调用对象:

1. 函数

2. 函数指针

3. lambda表达式

4. 重载了函数调用运算符的类

5. bind创建的对象

函数不能定义在另一个函数内, 但是 lambda表达式可以定义在函数内。

一.什么是 lambda表达式

        一个lambda表达式 表示一个可调用的代码单元,可理解为 一个未命名的内联函数。一个lambda表达式具有一个返回类型、一个参数列表 和 一个函数体。表达式形式如下:

        [capture list ] ( parameter list)  -> return type { function  body }

capture list :  捕获列表

return  type :  返回类型

parameter list:参数列表

function body: 函数体 

捕获规则:

捕获规则是指Lambda表达式捕获外部变量的方式。C++11标准规定了三种捕获方式:

  • 值捕获(Capture by value):使用[=]表示 以值方式 捕获所有的外部变量,Lambda表达式中的外部变量会被复制一份,修改Lambda表达式中的变量不会影响外部变量。
  • 引用捕获(Capture by reference):使用[&]表示 以引用方式 捕获所有的外部变量,Lambda表达式中的外部变量是外部变量的引用,修改Lambda表达式中的变量会影响外部变量。              [this]表示 以引用方式 捕获当前对象的指针,可以在Lambda表达式中访问当前对象的成员变量和成员函数。
  • 显式捕获(Explicit capture):使用[var]表示捕获外部变量var,使用[&var]表示捕获外部变量var的引用,使用[=var]表示捕获外部变量var的副本,使用[&, var]表示以引用方式捕获所有的外部变量并捕获外部变量var的副本,使用[=, &var]表示以值方式捕获所有的外部变量并捕获外部变量var的引用。

Lambda表达式可以使用任意的组合方式,例如[this, a, b](int c){}表示以引用方式捕获当前对象的指针,并以值方式捕获变量a和b,同时接受一个整型参数c。

捕获的时候,这个外部变量,外部的范围是哪些范围?

在Lambda表达式中捕获的外部变量,指的是 Lambda表达式定义的位置所在 的 外部作用域中 的变量。具体来说,Lambda表达式可以捕获以下外部变量:

  1. 局部变量:Lambda表达式可以捕获定义在Lambda表达式外部作用域中的局部变量,包括函数中的局部变量和全局变量。捕获局部变量的方式和捕获全局变量的方式相同,可以使用值捕获、引用捕获和显式捕获。
  2. 成员变量:如果Lambda表达式定义在类中,并且使用了this捕获了当前对象的指针,则Lambda表达式可以访问当前对象的所有成员变量。
  3. 静态变量:Lambda表达式可以捕获定义在外部作用域中的静态变量,可以使用值捕获、引用捕获和显式捕获。

需要注意的是,Lambda表达式只能捕获定义在Lambda表达式所在的外部作用域中的变量,不能捕获在Lambda表达式内部或者其他作用域中定义的变量。

如果需要在Lambda表达式中使用其他作用域中的变量,可以通过函数参数的方式传递进来。

lambda 必须使用  尾置返回  (比如 [ ](int a)-> int { ...... })来指定返回类型。 如果 忽略返回类型,lambda根据函数体中的代码推断出返回类型。

例如:

auto compare = [](const int a, const int b){ return a > b;}

在Lambda表达式的参数列表中,可以指定函数的参数,也可以使用默认参数,例如([](){})表示一个不带参数的Lambda表达式,([](int a){})表示一个带有一个整型参数的Lambda表达式。

在Lambda表达式的函数体中,可以编写任意有效的C++代码,包括语句、表达式、控制结构等。Lambda表达式可以返回一个值,也可以不返回任何值。

二、lambda的调用

调用方式与普通函数的调用方式相同,都是使用调用运算符() :

1.不使用捕获列表

示例1:

#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
    auto compare = [](const int a, const int b) {return a > b; };
    cout << "3 与 7的对比结果:"<<compare(3, 7) << endl;
    return 0;
}

运行结果是:

示例2:

sort函数,默认是从小到大排序,自定义按照string的大小进行排序

#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
    vector<string> mystring = {"a","egg","elephant","piggy","monkey","yellow","ahelkh","walawalawala"};


    sort(mystring.begin(), mystring.end(), [](const string a, const string b) {return a.size() > b.size(); });
    cout << "sort排序后的结果是:";
    for (auto mem:mystring)
    {
        cout << " " << mem;
    }
    cout << endl;

   
    system("pause");
    return 0;
}

运行结果:

2.使用捕获列表

lambda以一对 [ ] 开始,可以在其中提供一个以逗号分隔的名字列表 , 这些名字都是 它所在函数中定义的。

示例1:

#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{ 
    //使用捕获列表
    //
    string a = "hlloy high";
    string b = "what?";
    auto compare= [a,b](const string c)
    {
        return c.size() > a.size() && c.size() >b.size();
    };

    cout << compare("WoWwwww  you get one goald") << endl;

    system("pause");
    return 0;
}

运行结果是:

 示例2:

#include <iostream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;

int main()
{
    vector<string> mystring = {"a","egg","elephant","piggy","monkey","yellow","ahelkh","walawalawala"};

    //找到第一个大于6的字符串
    int sz = 6;
    auto wx = find_if(mystring.begin(), mystring.end(), [sz](const string a) {return  a.size() > sz; });
    cout <<"第一个大于 sz 大小的字符串是:"<< *wx << endl;


    system("pause");
    return 0;
}

 执行结果是:

三. 关于捕获是在什么时候捕获的

  1. 按值捕获:在 lambda 定义时 复制变量的当前值,后续对原变量的修改不会影响已捕获的值

  2. 按引用捕获:捕获变量的引用,后续对原变量的修改会反映在 lambda 中

  3. 默认捕获:

    • [=] 默认按值捕获所有外部变量

    • [&] 默认按引用捕获所有外部变量

     详细说明:

  1. 按值捕获:它直接捕获的是在 lambda 表达式定义那一刻,外部变量的当前值的一个副本。你可以把它想象成在 lambda 内部创建了一个新的、同名的常量(默认情况下)变量,并用外部变量的值初始化了它。

    int x = 10;
    // 这里,lambda 内部的 'x' 被创建并初始化为 10
    auto lambda = [x]() { return x + 1; };

  2. 按引用捕获:它不是捕获数值,而是捕获了外部变量的引用(别名)。它把外部变量的“门牌号”交给了 lambda。lambda 内部对这个名字的所有操作,都会直接作用到原来的那个变量上。

    int x = 10;
    // 这里,lambda 内部的 ‘x’ 是外部 ‘x’ 的一个别名(引用)
    auto lambda = [&x]() { x = 20; }; // 这会修改外部的 x

更形象的比喻

让我们用一个比喻来加深理解:

假设外部变量 a 是一个装着水的杯子,里面的水是它的值。

  • 按值捕获 [a]:

    • 行为:在 lambda 定义的那一刻,重新拿一个空杯子,从 a 杯子里倒同样多的水到这个新杯子里。

    • 结果:lambda 拥有的是一杯独立的水。之后无论你是喝掉原来杯子 a 里的水(修改原变量),还是往新杯子里加水,两者都互不影响。

  • 按引用捕获 [&a]:

    • 行为:没有新杯子。lambda 只是知道了原来那个杯子 a 放在哪里(拿到了它的地址)。

    • 结果:lambda 内部对 a 的任何操作,比如喝水、倒水,都是在操作原来那个杯子。外界看到的就是这个杯子的变化。

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

相关推荐

C++ Lambda表达式

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

weixin_54859557的博客 769

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++中的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万+

C++11:lambda表达式

lambda表达式就是定义了一个可调用的匿名函数,一般在局部。1.格式mutable捕捉列表 参数去const(单词意思易变的)返回值 函数体};2. lambda表达式各部分说明,该列表总是出现在lambda函数的开始位置,,。捕捉的参数都是自带const的,想要去掉const属性可以用mutable,但是捕捉的对象(变量)仍是一份拷贝,外部的a,b无法被修改,所以mutable 很少用,意义不大,不如用 [&]引用捕捉 ( )引用传参。

zhang_si_hang的博客 1万+

构建多节点AI代理网络:OpenClaw协同框架与实战部署指南

在分布式系统与AI代理技术领域,多节点协同是提升智能体能力与扩展性的核心挑战。其原理在于通过设计清晰的通信协议与数据同步机制,使分散的智能体能够共享状态、知识与技能,从而实现1+1>2的群体智能。这一技术价值在于突破了单点AI的能力上限,为构建复杂、鲁棒且可扩展的自动化系统提供了基础。典型的应用场景包括跨设备任务编排、企业级工作流自动化以及大规模AI代理集群的管理。本文聚焦于OpenClaw这一开源AI代理框架,深入探讨如何利用模块化设计(如网状网络与任务控制中心)实现记忆共享与统一调度,解决多网关协同中的

weixin_42521032的博客 298

【Spring源码三千问】哪些循环依赖问题Spring解决不了?

哪些循环依赖问题Spring解决不了?前言版本约定正文场景一: prototype 类型的循环依赖场景二: constructor 注入的循环依赖场景三:Proxy 类型的 Bean 的循环依赖小结 系列博文: 【老王读Spring IoC-0】Spring IoC 引入 【老王读Spring IoC-1】IoC 之控制反转引入 【老王读Spring IoC-2】IoC 之 BeanDefinition 扫描注册 【老王读Spring IoC-3】Spring bean 的创建过程 【老王读Spring I

老王的专栏 7319

C++中的Lambda表达式详解

一直都在提醒自己,我是搞C++的;但是当C++11出来这么长时间了,我却没有跟着队伍走,发现很对不起自己的身份,也还好,发现自己也有段时间没有写C++代码了。今天看到了C++中的Lambda表达式,虽然用过C#的,但是C++的,一直没有用,也不知道怎么用,就可怜的连Lambda语法都看不懂。好了,这里就对C++中的Lambda进行一个简单的总结,就算是对自己的一个交代,我是搞C++的,我是一个C+

NickWei的博客 4万+

基于STM32与ESP8266的MQTT协议实现阿里云物联网平台远程LED控制

本文详细介绍了如何利用STM32单片机与ESP8266 Wi-Fi模块,通过MQTT协议连接阿里云物联网平台,实现远程控制LED灯的完整物联网项目。内容涵盖硬件连接、阿里云平台配置、MQTT协议与AT指令解析、STM32代码实战以及数据解析与调试技巧,为嵌入式开发者提供了一个清晰、实用的物联网入门实践指南。

svm4gardener的博客 792

Cpp || lambda 表达式

lambda表达式的使用注意方式

Template Code 2588

实战避坑:示波器测量非隔离开关电源的炸机风险与隔离方案

本文详细分析了使用示波器测量非隔离开关电源时的炸机风险,揭示了地线环路导致的短路问题,并对比了四种防炸机解决方案,包括示波器隔离供电、拔掉电源地线、使用差分探头和被测板隔离供电。重点推荐使用隔离变压器方案,确保测量安全与精度,同时提供了实操建议与经验分享,帮助工程师避免常见测量事故。

weixin_29224309的博客 561

使用VNA(Vector Network Analyzer)对S参数进行去嵌(一)

传统上,RF和微波组件被设计成具有同轴接口的封装。通过连接一系列这些单独的同轴设备,可以容易地制造复杂的系统。使用使用类似同轴接口的标准测试设备可以很容易地测量这些部件和系统的性能。然而,现代系统需要更高水平的组件集成、更低的功耗和更低的制造成本。射频组件正在迅速从使用昂贵同轴接口的设计转向使用印刷电路板和表面贴装技术(SMT)的设计。传统的同轴接口甚至可以从最终产品中取消。这就给设计者留下了用需要同轴接口的测试设备测量这些射频和微波组件性能的问题。解决方案是使用连接同轴和非同轴传输线的测试夹具。

小孟同学的博客 1万+

【C++】Lambda表达式

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

AAADiao的博客 1万+

Vue3 - 手机移动端H5网页强力解决弹起软键盘后页面被挤压变形或页面整体上移问题,点击input输入框键盘弹出底部被上推往上顶遮挡及各种问题(兼容安卓苹果ios手机,微信公众号网页微信内置浏览器)

vue3,h5网页,input输入框组件,vue3 h5软键盘弹出,vue3输入框,键盘弹起时页面整体上移问题,uni,H5页面,解决软键盘弹起页面被挤压、被往顶的问题,解决vue3输入框,键盘弹起时页面整体上移问题,vue3调用手机系统软键盘,页面窗口被顶起,布局定位失效,解决VUE3软键盘弹起导致页面fixed定位元素被顶上去,输入法软键盘弹起,窗口顶起,变形解决办法,Vue中input组件在IOS设备上弹出软键盘时页面整体上移问题的解决方案,以及input组件聚焦后弹出软键盘固定在,Vue3软键盘把界

🏆 前端领域优质创作者 1万+

C++ 11 Lambda表达式

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

键盘上狂欢 5223

如何使用DPABI 进行核磁共振数据结果统计分析?

下面总结使用DPABI 的统计模块对MRI 图像进行统计分析的基本方法,并与SPM 的统计结果进行简单的对比。DPABI 的统计模块包含了常用的统计模型和多重比较校正方法、在控制协变量上也非常方便。 DPABI 进行结果统计分析一、下载和安装 DPABI二、下载样例数据三、统计模型和多重比较校正四、DPABI 的统计主界面五、DPABI 的可视化主界面六、查看统计结果 一、下载和安装 DPABI 下载 DPABI 包,解压后将文件夹和子文件夹加入MATLAB 的搜索路径即可。 具体安装方法详见 dpabi

从事脑科学核磁共振方法学研究,在Nature communications等权威期刊发表研究论文,熟练掌握磁共振处理方法和统计学方法,欢迎大家和我交流。 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

CPP中的lambda表达式

leetcode56.合并区间lambda表达式用于自定义sort比较函数public ://用lambda表达式来自定义sort sort(intervals . begin() , intervals . end() , [ ](const vector < int > & a , const vector < int > & b) {}));//把第一个元素加进去 result . push_back(intervals [ 0 ]);//开始遍历 for(int i = 1;

CFY1226的博客 1053

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

【C++】lambda 表达式

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

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

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

C++ 中的 Lambda 表达式

在 C++ 11 和更高版本中,Lambda 表达式(通常称为 Lambda)是一种在被调用的位置或作为参数传递给函数的位置定义匿名函数对象(闭包)的简便方法。 Lambda 通常用于封装传递给算法或异步函数的少量代码行。 本文将提供 Lambda 的定义、将它与其他编程技术进行比较。 其中介绍了各自的优点,并提供了一些基本示例。

Him__的博客 1320

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

C++11——Lambda表达式

weixin_60478154的博客 4544

cpp lambda表达式

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

ZnS_oscar的博客 363

c++中 Lambda表达式

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

2401_88413914的博客 1018

c++ Lambda 表达式

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

如履薄冰 1092
上一篇: Linux下 UDP 服务端和客户端回声实现
下一篇: TCP 与 UDP的区别
Monkey Ji
博客等级 码龄9年 113粉丝 71原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值