【C++】C++11:lambda、包装器
C11lambda、包装器1、lambda表达式1.1 lambda表达式语法lambda 表达式本质是一个匿名函数对象跟普通函数不同的是他可以定义在函数内部。我们⼀般是用auto或者模板参数定义的对象去接收lambda 对象。#includeiostreamusingnamespacestd;intmain(){// [] 捕获列表() 参数- 返回值可省略{} 函数体autofunc[](){cout这是lambda匿名函数endl;};// 调用lambda// 输出这是lambda匿名函数func();return0;}lambda表达式的格式[capture-list] (parameters)- return type { function boby }[capture-list]捕捉列表捕捉外面的变量供lambda函数使用捕捉列表为空也不能省略(parameters)lambda的形参列表用来传参与普通函数的参数列表功能类似如果不需要参数传递则可以连同()一起省略-return type返回值类型指定返回值类型一般返回值类型明确情况下可以省略由编译器对返回类型进行推导{function boby}函数体和普通函数大括号完全一样写逻辑、循环、判断、return、cout 输出全都放这里。egintmain(){autoadd1[](intx,inty)-int{returnxy;};coutadd1(1,2)endl;// 输出3// 1、捕捉为空也不能省略// 2、参数为空可以连同()一起省略// 3、返回值可以省略可以通过返回对象自动推导// 4、函数体不能省略autofunc1[]{couthelloendl;return0;};func1();// 输出hellointa0,b1;autoswap1[](intx,inty){inttmpx;xy;ytmp;};swap1(a,b);couta:bendl;// 输出1:0return0;}1.2 lambda和sort排序使用sort排序structGoods{string _name;// 名字double_price;// 价格int_evaluate;// 评价// ...Goods(constchar*str,doubleprice,intevaluate):_name(str),_price(price),_evaluate(evaluate){}};// 按价格升序structCompare1{booloperator()(constGoodsgl,constGoodsgr){returngl._pricegr._price;}};// 按价格降序structCompare2{booloperator()(constGoodsgl,constGoodsgr){returngl._pricegr._price;}};// 按评价分数降序structCompare3{booloperator()(constGoodsgl,constGoodsgr){returngl._evaluategr._evaluate;}};intmain(){vectorGoodsv{{苹果,2.1,5},{香蕉,3,4},{橙子,2.2,3},{菠萝,1.5,4}};sort(v.begin(),v.end(),Compare1());sort(v.begin(),v.end(),Compare2());sort(v.begin(),v.end(),Compare3());}使用sort后可读性较差逻辑复杂使用lambda表达式修改#includevector#includealgorithmstructGoods{string _name;// 名字double_price;// 价格int_evaluate;// 评价// ...Goods(constchar*str,doubleprice,intevaluate):_name(str),_price(price),_evaluate(evaluate){}};intmain(){// 价格降序autopriceLess[](constGoodsgl,constGoodsgr){returngl._pricegr._price;};sort(v.begin(),v.end(),priceLess);sort(v.begin(),v.end(),[](constGoodsgl,constGoodsgr){returngl._pricegr._price;});sort(v.begin(),v.end(),[](constGoodsgl,constGoodsgr){returngl._evaluategr._evaluate;});sort(v.begin(),v.end(),[](constGoodsgl,constGoodsgr){returngl._evaluategr._evaluate;});}用lambda表达式后不用单独写一个struct仿函数不需要额外定义类1.3 捕捉列表lambda表达式中默认只能用lambda 函数体和参数中的变量如果想用外层作用域中的变量就需要进行捕捉第一种在捕捉列表中显示的传值捕捉[var]和传引用捕捉[var]捕捉的多个变量用逗号分割intx0;intmain(){// 只能用当前lambda局部域和捕捉的对象和全局对象inta0,b1,c2,d3;autofunc1[a,b]()mutable{// 值捕捉的变量不能修改引用捕捉的变量可以修改//a;b;x;intretab;returnret;};coutfunc1()endl;// 输出3}第二种在捕捉列表中隐式捕捉[]表示隐式值捕捉[]表示引用方式传递捕捉所有父作用域中的变量这样我们lambda表达式中⽤了那些变量编译器就会自动捕捉那些变量intmain(){inta0,b1,c2,d3;// 隐式值捕捉// 用了哪些变量就捕捉哪些变量autofunc2[]{intretabc;returnret;};coutfunc2()endl;// 输出3// 隐式引用捕捉// 用了哪些变量就捕捉哪些变量autofunc3[]{a;c;d;};func3();// 输出1 1 3 4couta b c dendl;}第三种在捕捉列表中混合使用隐式捕捉和显示捕捉[, x]表示其他变量隐式值捕捉x引用捕捉[, x, y]表示其他变量引用捕捉x和y值捕捉intmain(){// 只能用当前lambda局部域和捕捉的对象和全局对象inta0,b1,c2,d3;// 混合捕捉1autofunc4[,a,b]//其他都是引用捕捉a和b是值捕捉不能放到中间{//a;//b;c;d;returnabcd;};func4();// 输出0 1 3 4couta b c dendl;// 混合捕捉2autofunc5[,a,b]//其他都是值捕捉a和b是引用捕捉{a;b;/*c; d;*/returnabcd;};func5();// 输出1 2 3 4couta b c dendl;return0;}注意值传递方式捕捉的变量默认情况下是被const修饰的也就是说传值捕捉的变量不能修改如果想修改可以在参数列表的后面加mutable取消其常量性例如autofunc7[]()mutable{a;// a可修改b;c;d;returnabcd;};coutfunc7()endl;couta b c dendl;语法上捕捉列表可以有多个项组成例如[, a, b]其他都是引用捕捉a和b是值捕捉只能放在列表的开头[a, , b]是错误的捕捉列表不允许变量重复传递否则会导致编译出错例如[, a]出现了两个值捕捉导致重复2、functionstd::function是一个类模板是C提供的函数包装器类模板不管是普通函数、函数指针、仿函数、lambda、bind绑定出来的可调用对象std::function相当于一个统一的盒子能把它们全部装进去统一形成一种类型templateclassTclassfunction;// undefinedtemplateclassRet,class...ArgsclassfunctionRet(Args...);//eg:接收两个int参数返回int的可调用对象盒子functionint(int,int)函数指针、仿函数、lambda等可调用对象的类型各不相同std::function的优势就是统一类型对他们都可以进行包装这样在很多地方就方便声明可调用对象的类型#includefunctional// 计算两数相加intf(inta,intb){returnab;}// 仿函数结构体structFunctor{public:intoperator()(inta,intb){returnab;}};// 包含多种函数classPlus{public:// 构造函数Plus(intn10):_n(n){}// 静态成员函数staticintplusi(inta,intb){returnab;}// const普通成员函数doubleplusd(doublea,doubleb)const{return(ab)*_n;}private:int_n;};intmain(){//函数指针// void(*pf)(int) nullptr;// 包装各种可调用对象functionint(int,int)f1f;// 全局函数functionint(int,int)f2Functor();// 仿函数functionint(int,int)f3[](inta,intb){returnab;};// lamdbacoutf1(1,1)endl;// 2coutf2(1,1)endl;// 2coutf3(1,1)endl;// 2// 把function放进vector容器中vectorfunctionint(int,int)vf{f,Functor(),[](inta,intb){returnab;}};for(autof:vf){coutf(1,1)endl;// 输出2}// 包装静态成员函数// 成员函数要指定类域并且前面加才能获取地址functionint(int,int)f4Plus::plusi;coutf4(1,1)endl;// 普通成员函数隐藏第一个参数即this参数所以要加上Plus*functiondouble(Plus*,double,double)f5Plus::plusd;Plus ps;coutf5(ps,1.1,1.1)endl;// 输出22// 第二种包装plusd接收const对象引用// const Plus 可以接收普通对象、临时对象不用传指针//functiondouble(Plus, double, double) f6 Plus::plusd;functiondouble(constPlus,double,double)f6Plus::plusd;coutf6(Plus(),1.1,1.1)endl;// Plus()是临时对象匹配const引用输出22coutf6(ps,1.1,1.1)endl;// 传入局部对象ps输出22// 右值引用版本Plus仅能接收临时对象、std::move转换后的右值对象functiondouble(Plus,double,double)f7Plus::plusd;coutf7(Plus(),1.1,1.1)endl;// Plus()临时右值匹配Plus输出22coutf7(move(ps),1.1,1.1)endl;// move把ps转为右值匹配Plus输出22return0;}总结三种传对象的方式区别Plus*传对象地址const Plus万能普通对象、临时对象都能接Plus只接收临时右值或者 move 转换后的对象3、bindbind是一个函数模板也是一个可调用对象的包装器接收任意可调用对象返回一个新的可调用对象它可以用来调整参数个数和参数顺序// 版本1自动推导返回值templateclassFn,class...Args/* unspecified */bind(Fnfn,Args...args);// 版本2手动指定返回值templateclassRet,classFn,class...Args/* unspecified */bind(Fnfn,Args...args);bind的一般形式auto newCallable bind(callable,arg_list);newCallable可调用对象callable代表原始可调用对象就是你想要改装的函数arg_list是逗号分隔的参数分两种类型1、固定常量数字 / 变量 / 对象2、占位符 _1 _2 _3_1为newCallable的第⼀个参数_2为第⼆个参数以此类推#includefunctionalusingplaceholders::_1;usingplaceholders::_2;usingplaceholders::_3;intSub(inta,intb){return(a-b)*10;}intSubX(inta,intb,intc){return(a-b-c)*10;}intmain(){coutSub(10,5)endl;// bind 本质返回的一个仿函数对象// 调整参数顺序不常用// _1代表第一个实参// _2代表第二个实参// ...// _2填给Sub的第一个形参a_1 填给 Sub 的第 2 个形参 bautonewSub1bind(Sub,_2,_1);coutnewSub1(10,5)endl;// 调整参数个数// _1填给Sub的a常量10固定填给Sub的bautonewSub2bind(Sub,_1,10);coutnewSub2(20)endl;// 常量5固定填给Sub的a_1填给Sub的bautonewSub3bind(Sub,5,_1);coutnewSub3(20)endl;// 常量5填给SubX的a_1填给SubX的b_2填给SubX的cautonewSub4bind(SubX,5,_1,_2);coutnewSub4(10,20)endl;// _1填给SubX的a常量5填给SubX的b_2填给SubX的cautonewSub5bind(SubX,_1,5,_2);coutnewSub5(10,20)endl;// _1填给SubX的a_2填给SubX的b常量5填给SubX的cautonewSub6bind(SubX,_1,_2,5);coutnewSub6(10,20)endl;写_n调用新函数时传入的第 n 个实参会填充到这个原函数形参位置

相关新闻

机器学习模型生产化:从部署到高可用的四大工程支柱

机器学习模型生产化:从部署到高可用的四大工程支柱

1. 项目概述:当模型走出笔记本,真正开始“呼吸”现实世界你有没有经历过这样的时刻?模型在 Jupyter Notebook 里跑得飞起,AUC 0.92,F1 0.88,交叉验证稳如老狗;团队围在白板前击掌庆祝&#xff0…

2026/10/5 13:16:51 阅读更多 →
AM62L硬件防火墙实战:从寄存器精读到多区域安全配置

AM62L硬件防火墙实战:从寄存器精读到多区域安全配置

1. AM62L硬件防火墙:从寄存器手册到实战配置的深度解析在嵌入式系统,尤其是汽车电子和工业控制这类对功能安全要求极高的领域,系统安全不再是“锦上添花”,而是“生死攸关”的底线。一个未经授权的内存访问,可能导致关…

2026/10/4 12:40:08 阅读更多 →
ROC曲线本质:二分类模型的阈值决策地形图

ROC曲线本质:二分类模型的阈值决策地形图

1. 这不是一张“好看”的图,而是一把手术刀:ROC曲线到底在切什么?你第一次看到ROC曲线,大概率是在某篇论文的Figure 3里——一条从左下角斜着爬向右上角的弧线,旁边密密麻麻标着AUC0.87、0.92、0.95……然后你默默记下…

2026/9/22 10:42:01 阅读更多 →

最新新闻

MySQL JSON类型完全指南:从函数使用到索引优化与JSON_TABLE实战

MySQL JSON类型完全指南:从函数使用到索引优化与JSON_TABLE实战

MySQL 的 JSON 数据类型从 5.7 引入到现在快十年了,但我在实际项目里见到的大量用法,还停留在“把 JSON 塞进 TEXT 字段,查询时全表捞出来再用程序解析”这种原始阶段。等到数据量上来、接口响应变慢、想按 JSON 里的某个字段过滤却没法走索引…

2026/10/5 13:48:17 阅读更多 →
数据库索引底层原理:B+树、哈希索引与联合索引设计

数据库索引底层原理:B+树、哈希索引与联合索引设计

前几天有个同事带着一脸困惑跑来找我,说他写了一条SQL,where条件里两个字段都建了索引,执行计划却告诉你他根本没走索引。我一问,表里建了两个单列索引,优化器觉得还不如全表扫描,执行计划果断把索引扔了。…

2026/10/5 13:48:16 阅读更多 →
JavaScript开发者必备工具包:2023最新调查数据解读

JavaScript开发者必备工具包:2023最新调查数据解读

大家好,今天和大家分享一份关于 JavaScript 开发的最新调查数据。这份报告来自 JetBrains 的开发者环境调查,覆盖了全球 26,348 名开发者的真实使用情况。数据涵盖编程语言、工具、框架等多个方面,尤其对 JavaScript 和 TypeScript 的使用趋势…

2026/10/5 13:48:16 阅读更多 →
PiDiNet:用像素差分卷积实现轻量级边缘检测

PiDiNet:用像素差分卷积实现轻量级边缘检测

做边缘检测的人,大概率都经历过这样一个阶段:先学Sobel、Prewitt这些经典算子,觉得简单又直观,后来接触深度学习,发现HED、RCF这类CNN模型效果确实好,但那动辄几十上百兆的参数,又让你觉得它离“…

2026/10/5 13:48:16 阅读更多 →
基于FPGA的等精度测频法实现低频方波频率与占空比测量

基于FPGA的等精度测频法实现低频方波频率与占空比测量

做低频方波测量,很多人第一反应是拿单片机定时器数一数就行了。但真要同时把频率和占空比都测准,还要应对不同频率范围、边沿抖动、实时输出这些需求,单片机方案往往会在精度和灵活度上卡脖子。这篇笔记就是记录我用FPGA做低频方波频率与占空…

2026/10/5 13:48:16 阅读更多 →
插件系统设计实战:从plugin.json到TypeScript SDK与CLI

插件系统设计实战:从plugin.json到TypeScript SDK与CLI

1. 插件系统到底解决了什么问题第一次接触插件机制是在给一个内部工具做扩展功能的时候。当时的需求很朴素:主程序已经上线了,但业务方隔三差五就要加一个小功能,每次都得改主程序、重新打包、重新发版。改到第五次的时候我意识到&#xff0c…

2026/10/5 13:47:16 阅读更多 →

日新闻

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

马斯克杀回智能体战场,Grok 4.5万亿参数撑腰,Cursor接手数字白领项目:用TaoToken统一Key跑通多模型Agent工作流

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:22 阅读更多 →
AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

AI编程工具插件机制详解:plugin.json配置与加载失败排查指南

1. 从“plugins”这个词说起:它到底在解决什么问题如果你最近在折腾 AI 编程工具,尤其是 Cursor、Codex CLI、Claude Code 这类带 CLI 的编辑器或命令行助手,那你大概率绕不开一个词——plugins。这个词本身不新鲜,从浏览器到 IDE…

2026/10/5 0:00:23 阅读更多 →
第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

第26课:OpenClaw|日志审计与问题诊断:把日志链路改到 TaoToken 的排查清单

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 0:00:23 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 5:06:42 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 1:10:22 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/5 3:06:17 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 11:40:45 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 9:43:54 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/4 20:14:29 阅读更多 →