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

C++11(三)lambda表达式、function、bind

一、lambda1. lambda表达式语法lambda表达式本质是一个匿名函数对象这个原理部分会讲到不过与普通函数只能定义在全局或类内部不同它可以直接定义在函数内部。lambda表达式格式代码语言javascriptAI代码解释[capture_list] (parameters) - return type { function boby };[capture_list]捕捉列表存在于lambda函数起始位置它的存在能让编译器识别出这是一个lambda函数。作用捕捉列表能够捕捉上下文里的局部变量和参数供lambda函数使用全局变量、静态变量可以直接使用。即使什么都不捕捉捕捉列表也不能省略。因为编译器要通过它来识别这个lambda函数。(parameters)参数列表和普通函数一样参数列表功能一样不过如果不用传参且不显式指定返回值类型的话()是能够省略的但如果使用了之后会讲到的mutable修饰符参数列表便不可省略。- return type返回值类型这里是返回值类型的尾置语法也就是把返回值类型放在了参数列表的后面。如果没有返回值的话这里可以省略。也可以不写纯靠编译器推理出这里的返回值类型。{ function boby }函数体这里和普通函数没有什么区别。可以在里面使用捕捉列表捕捉到的变量、传递来的形参、在内部定义的变量以及全局变量、静态变量。函数体为空也不能省略。lambda表达式在编译时会被转换为一个匿名类这个类的实例就是lambda函数对象。我们通过这个匿名函数对象来调用lambda。lambda表达式对于语法使用层面没有类型我们一般是通过auto或者是模板参数定义的对象都可以依靠编译器去推理去接收lambda对象。代码语言javascriptAI代码解释auto add [](int x, int y)-int { return x y; }; int n add(1, 2); cout n endl;在这里插入图片描述[](int x, int y)-int { return x y; };是一个lambda表达式也就是一个匿名函数对象我通过变量add来接收这个对象。之后通过add来调用这个lambda函数。2. 捕捉列表和mutable关键字lambda表达式默认是只能使用lambda函数体和参数列表中的变量以及全局变量静态变量。如果想要用外层作用域中的变量就要进行捕捉。第一种捕捉方式是显式在捕捉列表里传值捕捉和传引用捕捉。捕捉的多个变量之间需要用逗号进行分割比如[ x, y, z]其中x和y是传值捕捉z是传引用捕捉。第二种捕捉方式是隐式捕捉它也包含传值捕捉和传引用捕捉捕捉列表里是就是传值捕捉是就是传引用捕捉。它们会根据函数体内使用了外层作用域的哪些变量来进行自动捕捉也就是编译器自动捕捉所有使用到的变量。[]与[]第三种捕捉方式是混合捕捉也就是显式捕捉和隐式捕捉结合在一起使用。不过隐式捕捉或者一定要是第一个元素且能和混合使用的一定是显式引用捕捉和混合使用的一定是显式传值捕捉。比如[, x, y][, x, y]。lambda表达式如果在函数局部域中他可以捕捉lambda表达式之前所定义的变量但不能捕捉全局变量和静态变量这两个不用捕捉就能直接使用。这同时也意味着如果lambda表达式如果定义在全局捕捉列表必须为空。在这里插入图片描述传值捕捉不能通过修改这个捕捉来的变量来影响外层作用域的变量因为是副本但传引用捕捉是直接修改外层作用域变量的除非原变量不可修改。由于lambda捕捉列表是被const修饰的也就是说传值捕捉过来的变量是不能进行修改的如果要修改则需要在捕捉列表后面加上修饰符mutable这样可以取消它的常量性但由与传值捕捉的是副本所以就算可以修改这个捕捉过来的变量也是不能够影响到外层作用域的变量的实参。使用mutable修饰符后参数列表即使为空也不能够省略。代码语言javascriptAI代码解释int a 1, b 2; auto add [a, b]()mutable { a 2; b 5; }; add(); cout a b endl;在这里插入图片描述可以看到a即使被mutable解除常性也无法影响实参而b引用捕捉却可以。3. lamba的原理lamba表达式的底层是一个仿函数类。这个仿函数的类名是编译器根据特定规则生成的保证不同lambda生成的类名不同。lambda表达式捕捉列表去捕捉变量本质就是生成这个lambda类的成员变量也就是说捕捉列表里的变量会作为这个匿名类的成员变量并在创建lambda对象时通过构造函数进行初始化。对于传值捕捉这些成员变量是外部变量的副本对于传引用捕捉这些成员变量是引用。这也能完全解释为何传值无法影响到外层作用域的变量因为操作的是副本而后面的参数列表返回值和函数体则对应lambda类中operator()的重载。代码语言javascriptAI代码解释auto add [a, b]()mutable { a 2; b 5; }; class 类名//类名由编译器生成 { public: 类名(int a, int b) :_a(a) ,_b(b) {} void operator()()//如果没有mutable后面加上const { _a 2; _b 5; } private: int _a; int _b; };4. 应用在学习lambda表达式之前我们能够使用的可调用对象只有函数指针和仿函数对象函数指针的定义和定义仿函数定义一个类都比较麻烦。而有了lambda表达式之后功能和仿函数一样用它去定义简单又方便。二、包装器1. function在这里插入图片描述std::function是一个类模板也是一个包装器。它的实例对象可以包装其他的可调用对象比如lambda表达式函数指针、仿函数、bind表达式等。存储的可调用对象称作std::function的目标。如果std::function不含目标则称它为空空的std::function在使用时会抛异常。函数指针、仿函数、lambda表达式、bind表达式等可调用对象的类型各不相同而function则可以统一它们的类型类型擦除变成std::function类型。这样方便之后统一的存储和调用比如存进容器里面。使用function可调用对象返回类型(可调用对象参数类型) 对象名称 可调用对象。对于类成员函数c规定要指定类域并取地址。使用function和之后会讲到的bind需要包含头文件functional。代码语言javascriptAI代码解释#includefunctional int f(int a, int b) { return a b; } struct Functor { public: int operator() (int a, int b) { return a b; } }; class Plus { public: Plus(int n 10) :_n(n) {} static int plusi(int a, int b) { return a b; } double plusd(double a, double b) { return (a b) * _n; } private: int _n; }; int main() { //包装各种可调用对象 functionint(int, int) f1 f; functionint(int, int) f2 Functor(); functionint(int, int) f3 [](int a, int b) {return a b; }; //包装静态成员函数成员函数需要指定类域且前面加才能获取地址 functionint(int, int) f4 Plus::plusi; //不过静态成员函数前面可以不加但是推荐加 functionint(int, int) f5 Plus::plusi; //包装普通类成员函数不要忘了成员函数的第一个参数是this指针。 Plus obj; //传递对象指针-最常用的方式 functiondouble(Plus*, double, double) f6 Plus::plusd; double r1 f6(obj, 1.1, 2.2);//传递地址 //传递对象--有拷贝 functiondouble(Plus, double, double) f7 Plus::plusd; double r2 f7(obj, 1.1, 2.2); //传递右值引用 functiondouble(Plus, double, double) f8 Plus::plusd; double r3 f8(move(obj), 1.1, 2.2); //传递左值引用 functiondouble(Plus, double, double) f9 Plus::plusd; double r4 f9(obj, 1.1, 2.2); return 0; }function包装类普通成员函数的第一个参数不是this指针类型而是调用成员函数所需的一个媒介的类型无论是对象指针还是对象对象引用都是一个调用成员函数的媒介编译器通过这些媒介来获取实际的this指针。如果要包装类普通成员函数要将第一个参数加上const那么对应的函数也要加上const进行修饰权限不能放大。2. bindbind是一个函数模板同时它也是一个可调用对象的包装器。它会将接收的可调用对象进行一个再加工处理然后返回一个可调用对象比如用来调整参数个数和参数顺序。bind也在finctional这个头文件中。调用bind的一般形式是auto newCallable bind(callable, arg_list);其中newCallable是一个加工完成之后的可调用对象arg_list是一个逗号分隔的参数列表callable是要加工的可调用对象这个newCallable的arg_list参数列表对应的就是callable的参数列表。当我们调用newCallable时newCallable会调用callable然后将自己的参数列表arg_list传递给callable的参数列表。arg_list中的参数一般包含形如_n的名字其中n是一个整数这些参数是占位符表示newCallable的参数。数值n表示的是生成的可调用对象中参数的位置。_1就是第一个需要传递给newCallable的参数_2是第二个以此类推。改变顺序是改变像_1_2这样的参数在参数列表中的位置而调整参数个数是通过给定值来达到使用newCallable时就不用传递定值所在位置的实参newCallable在传递参数给callable时会把这个定值当作实参之一。

相关文章:

C++11(三)lambda表达式、function、bind

一、lambda 1. lambda表达式语法 lambda表达式本质是一个匿名函数对象(这个原理部分会讲到),不过与普通函数只能定义在全局或类内部不同,它可以直接定义在函数内部。lambda表达式格式: 代码语言:javascr…...

光伏产业价值链迁移:从硬件制造到系统服务与金融创新的黄金机遇

1. 光伏行业的价值转移:从硬件制造到系统服务十年前,当我在深圳第一次接触光伏组件生产线时,满眼都是硅料、银浆和层压机,行业里人人谈论的是转换效率又提升了零点几个百分点,或是每瓦成本又降了几分钱。那时候&#x…...

Unity 2D横版闯关游戏:从零到一构建像素风丛林冒险

1. 像素风游戏的前期准备 第一次打开Unity时,看着空荡荡的场景视图,我完全不知道从哪里开始。后来发现,制作2D横版游戏就像搭积木,需要先准备好所有零件。这里分享我制作《丛林法则》时的完整筹备过程。 像素风游戏最迷人的就是那…...

Dev Containers实战:容器化开发环境配置与团队协作指南

1. 项目概述:一个容器化的开发环境定义仓库如果你和我一样,经常需要在不同的机器上切换工作,或者团队里有新成员加入,那么“环境配置”这件事,绝对能排进程序员最头疼问题的前三名。我经历过无数次这样的场景&#xff…...

Linux 7.6 环境下 InterSystems Caché 数据库的部署与核心配置实战

1. 环境准备:打造Cach的温床 在RHEL 7.6最小化系统上部署InterSystems Cach前,我们需要像准备手术室一样严格配置基础环境。我曾在生产环境中因为漏掉一个依赖项导致整个安装流程卡住3小时,这些血泪经验都浓缩在下面的步骤里。 1.1 基础依赖安…...

S32K3 FlexCAN实战:从MCAL配置到DMA接收,手把手教你避开那些手册里没写的坑

S32K3 FlexCAN深度实战:从寄存器配置到DMA优化全链路解析 在车载电子架构快速迭代的今天,S32K3系列MCU凭借其强大的FlexCAN模块成为汽车电子开发者的首选。但官方文档往往只勾勒出理想状态下的功能框架,当工程师真正着手实现CAN FD通信时&…...

当计算机视觉模型开始“打架”:对抗性攻击与鲁棒性研究

摘要随着计算机视觉模型在安全敏感场景(如自动驾驶、人脸识别、安防监控)中的广泛应用,模型的脆弱性问题日益凸显。“打架”在这里并非字面意义的冲突,而是指对抗性攻击(Adversarial Attacks)与防御机制&am…...

微机原理课设别头疼!手把手教你用8255和8253芯片搞定电子琴仿真(附Proteus工程和汇编源码)

微机原理课设实战:82558253芯片构建电子琴仿真系统全解析 记得第一次拿到微机原理课设题目时,面对一堆芯片型号和汇编指令,我整个人都是懵的。作为过来人,我完全理解你现在可能面临的困惑——如何把抽象的芯片功能转化为实际可运行…...

别再死记硬背公式了!用‘井字棋’和‘抢30’游戏带你直观理解巴什博弈(Bash Game)

用童年游戏破解数学奥秘:从"抢30"到巴什博弈的思维跃迁 记得小时候和伙伴们玩"抢30"游戏吗?两人轮流报数,每次可以说1到3个连续数字,谁先喊出"30"谁就获胜。这个看似简单的游戏背后,隐藏…...

基于大语言模型的AI狼人杀游戏:双层角色扮演与模型竞技场设计

1. 项目概述:当狼人杀遇上AI,一场全新的推理盛宴毕业之后,想凑齐8到12个人,在周末的晚上围坐一圈,点上外卖,来一场酣畅淋漓的狼人杀,几乎成了一种奢望。这个游戏的精髓在于社交,但剥…...

别再求公司账号了!个人开发者也能搞定uniapp打包iOS(保姆级证书+profile配置)

个人开发者独立完成uniapp iOS打包全流程指南 在移动应用开发领域,iOS平台始终是开发者无法绕开的重要阵地。然而,许多独立开发者和小团队常常被苹果开发者账号的门槛所困扰,误以为必须依赖企业级账号才能完成应用打包和上架。实际上&#x…...

基于MCP协议的CalDAV/CardDAV集成:AI智能体统一管理日历与通讯录

1. 项目概述与核心价值最近在折腾智能体(Agent)和自动化工作流时,发现一个痛点:很多强大的工具和数据源,比如日历、邮件、云盘,它们都有自己独立的API,但要让AI智能体去理解和操作这些分散的系统…...

手把手教你用UE5 C++复刻《只狼》式动态攀爬:不止于ALS V4的拓展思路

UE5 C实现《只狼》式动态攀爬系统:从ALS V4到次世代交互设计 在动作游戏开发领域,玩家与环境的交互质量往往决定了游戏体验的上限。当《只狼:影逝二度》以其行云流水般的攀爬系统重新定义动作游戏标准时,许多开发者开始思考&#…...

外卖点餐连锁店餐饮生鲜奶茶外卖店内扫码点餐源码同城外卖校园外卖源码的扫码逻辑

📱 扫码点餐系统 - 完整扫码逻辑 源码示例外卖点餐 | 连锁店 | 餐饮生鲜 | 奶茶 | 店内扫码点餐 | 同城外卖 | 校园外卖🎯 扫码业务场景总览场景扫码后行为核心逻辑🍽️ 店内扫码点餐进入店铺菜单页识别店铺ID → 加载菜单🏃 外卖…...

XYBotV2:开发者如何快速构建可扩展的智能对话机器人框架

1. 项目概述:一个面向开发者的智能对话机器人框架最近在GitHub上看到一个挺有意思的项目,叫XYBotV2。乍一看标题,可能很多人会以为这又是一个普通的聊天机器人,但如果你点进去仔细研究一下,就会发现它其实是一个为开发…...

JAVA校园跑腿代买代拿社区-校园跑腿小程序的后端代码示例

&#x1f3c3; JAVA校园跑腿系统 - 后端完整代码示例校园跑腿代买代拿 | Spring Boot MyBatis Plus MySQL Redis&#x1f4e6; 一、项目依赖 pom.xmlxml<?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/…...

从一次内存拷贝崩溃说起:手把手教你用memcpy_s重构老旧C代码

从内存越界崩溃到安全重构&#xff1a;实战memcpy_s迁移指南 调试器突然停止在memcpy调用处&#xff0c;控制台抛出"Segmentation fault"的那一刻&#xff0c;每个C语言开发者都会心头一紧。这种由内存越界引发的崩溃在遗留代码库中尤为常见&#xff0c;就像我去年接…...

Cursor聊天数据恢复工具:原理、实操与避坑指南

1. 项目概述&#xff1a;数据恢复的“后悔药”在数字创作的世界里&#xff0c;我们与工具的交互正变得越来越智能和复杂。Cursor&#xff0c;这款集成了AI辅助编程能力的编辑器&#xff0c;已经成为了许多开发者和技术写作者的主力工具。它不仅仅是写代码&#xff0c;更是一个集…...

Go语言实现Dify与钉钉机器人集成:企业级AI应用开发实战

1. 项目概述&#xff1a;当Dify遇上钉钉&#xff0c;打造企业级AI应用新范式 最近在折腾一个挺有意思的项目&#xff0c;叫“MAyang38/dify-on-dingding-go”。光看名字&#xff0c;可能有点技术黑话的味道&#xff0c;但说白了&#xff0c;这就是一个“桥梁”项目。它的核心使…...

杰理之做1T1应用失真较大问题修改【篇】

可以将低延时编码LIVE_AUDIO_CODING_JLA_LL修改为LIVE_AUDIO_CODING_JLA...

基于MCP协议与Docker为Claude Code构建Brave搜索服务器Argus

1. 项目概述&#xff1a;为Claude Code打造一个“全视之眼” 如果你和我一样&#xff0c;日常重度依赖Claude Code来辅助编程、查资料、写文档&#xff0c;那你一定遇到过这样的痛点&#xff1a;当Claude需要联网搜索时&#xff0c;要么得手动复制粘贴&#xff0c;要么得依赖一…...

半导体行业如何应对政策不确定性:从游说策略到企业决策

1. 从一篇旧报道看半导体行业的“华盛顿困局”最近整理资料时&#xff0c;翻到一篇2012年EE Times的旧文&#xff0c;标题是《硅谷国度&#xff1a;选举后的政治僵局或将持续——SIA CEO如是说》。文章不长&#xff0c;但里面半导体行业协会&#xff08;SIA&#xff09;时任CEO…...

AI驱动终端交互:用自然语言指挥命令行的新范式

1. 项目概述&#xff1a;一个AI驱动的终端交互新范式最近在终端工具圈里&#xff0c;一个名为“yai”的项目引起了我的注意。它不是一个简单的命令行美化工具&#xff0c;也不是一个传统的终端复用器。简单来说&#xff0c;yai是一个由 AI 驱动的、旨在彻底改变你与终端交互方式…...

2025终极指南:Cursor Free VIP破解工具如何帮你免费解锁AI编程助手所有功能

2025终极指南&#xff1a;Cursor Free VIP破解工具如何帮你免费解锁AI编程助手所有功能 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Yo…...

从零构建C++/CUDA推理引擎:深入解析yalm项目与LLM底层优化

1. 项目概述&#xff1a;从零构建一个高性能的C/CUDA推理引擎最近在深入研究大语言模型推理的性能优化&#xff0c;发现很多开源实现为了追求极致的性能&#xff0c;代码往往高度优化&#xff0c;甚至引入了动态并行等高级CUDA特性&#xff0c;这对想深入理解底层原理的开发者来…...

BugPack:构建自动化安全研究工具箱的设计与实践

1. 项目概述&#xff1a;一个为安全研究量身定制的“漏洞工具箱”如果你是一名安全研究员、渗透测试工程师&#xff0c;或者是对软件安全有浓厚兴趣的开发者&#xff0c;那么你一定经历过这样的场景&#xff1a;在复现一个公开漏洞时&#xff0c;需要四处寻找可用的利用脚本&am…...

3大核心优势:Detect It Easy 如何成为文件类型识别的终极工具

3大核心优势&#xff1a;Detect It Easy 如何成为文件类型识别的终极工具 【免费下载链接】Detect-It-Easy Program for determining types of files for Windows, Linux and MacOS. 项目地址: https://gitcode.com/gh_mirrors/de/Detect-It-Easy 想象一下&#xff0c;你…...

基于MCP协议构建AI助手与外部应用桥接:以hikerapi-mcp为例的实战指南

1. 项目概述与核心价值最近在折腾一些自动化工作流&#xff0c;发现很多工具之间的数据流转是个大问题。比如&#xff0c;我想把某个文档里的关键信息提取出来&#xff0c;自动生成一个任务列表&#xff0c;再推送到另一个项目管理工具里。这个过程如果手动操作&#xff0c;不仅…...

27岁裸辞转网安:从传统行业到网安,我踩通了这条路

27 岁女生从传统行业裸辞转网络安全&#xff0c;3 个月拿到大厂 offer&#xff1a;这行真的没你想的那么难 后台经常收到私信&#xff0c;问我一个做了 4 年传统行业&#xff08;之前是线下品牌运营&#xff09;的女生&#xff0c;为什么突然 “跨界” 转做网络安全&#xff1…...

跨工具技能同步:构建统一操作习惯的中间层架构与实践

1. 项目概述&#xff1a;一个跨工具技能同步的构想在数字工具爆炸式增长的今天&#xff0c;我们每个人几乎都活在一个“工具丛林”里。作为一名长期与各种生产力工具、开发环境、设计软件打交道的从业者&#xff0c;我深刻体会到一种割裂感&#xff1a;在A工具里熟练无比的快捷…...