【C++】C++11 包装器function 与 绑定器 bind
目录一、 std::function可调用对象的类型擦除与统一包装1. 为什么需要 std::function2. std::function 语法与应用解析二、 std::bind参数绑定与调用适配1. std::bind 的核心机制2. std::bind 的语法与占位符三、 利用 bind 实现参数柯里化四、 核心总结在 C11 中可调用对象Callable Object包括函数指针、仿函数重载了operator()的类对象、Lambda 表达式以及类的成员函数 。这些类型各异的可调用对象在配合模板使用时会引发模板实例化膨胀问题 。为了统一和管理这些不同类型的可调用对象C11 引入了functional头文件中的std::function和std::bind。一、 std::function可调用对象的类型擦除与统一包装1. 为什么需要 std::function当我们将不同的可调用对象作为参数传递给函数模板时编译器会为每一种实际类型实例化出一份独立的代码 。templateclassF,classTTuseF(F f,T x){staticintcount0;coutcount:countendl;coutcount:countendl;returnf(x);}如果在实际调用中普通函数、仿函数对象和Lambda 表达式编译器会实例化出三份不同的useF函数 。这种行为会导致代码膨胀降低编译效率。std::function本质是一个类模板包装器/适配器 。它通过类型擦除技术能够在统一的接口下存储和调用任何具有相同调用签名的可调用对象。使用std::function接收参数可以强制所有兼容的可调用对象转换为同一种类型从而避免模板被多次实例化。2. std::function 语法与应用解析std::function的模板参数是函数的签名std::function返回值类型(参数类型列表)。#includeiostream#includefunctionalusingnamespacestd;// 1. 普通函数intf(inta,intb){returnab;}// 2. 仿函数structFunctor{intoperator()(inta,intb){returnab;}};// 3. 类包含静态与非静态成员函数classPlus{public:staticintplusi(inta,intb){returnab;}doubleplusd(doublea,doubleb){returnab;}};intmain(){// 包装普通可调用对象函数指针、仿函数、Lambdafunctionint(int,int)f1f;functionint(int,int)f2Functor();functionint(int,int)f3[](inta,intb){returnab;};coutf1(1,1)endl;coutf2(1,1)endl;coutf3(1,1)endl;// 包装静态成员函数// 静态成员函数属于类不依赖对象因此只需指定类域和取地址functionint(int,int)f4Plus::plusi;coutf4(1,1)endl;// 包装非静态成员函数// 深入解析非静态成员函数的底层第一个参数是隐藏的 this 指针。// 因此在 function 的参数列表中必须显式地增加一个类对象或类指针类型的参数。Plus pd;// 方式一传入对象指针Plus*functiondouble(Plus*,double,double)f5Plus::plusd;coutf5(pd,1.1,1.1)endl;// 调用时传入对象的地址// 方式二传入对象Plus底层通常是通过对象调用成员函数functiondouble(Plus,double,double)f6Plus::plusd;coutf6(pd,1.1,1.1)endl;// 传入具名对象coutf6(Plus(),1.1,1.1)endl;// 传入匿名对象return0;}关键点说明包装类的非静态成员函数时必须使用类名::函数名的严格语法取地址。同时由于非静态成员函数依赖this指针其实际参数列表比显式参数多一个对象指针/对象参数这一点在定义function类型时必须体现。二、 std::bind参数绑定与调用适配1. std::bind 的核心机制std::bind是一个函数模板它接收一个可调用对象并生成一个新的可调用对象 。它的核心作用是对现有函数的参数进行重新映射、固定或调整顺序。从底层来看std::bind返回的是一个未指定类型的仿函数对象。当我们调用这个生成的仿函数时它会将我们传入的参数与内部绑定的参数进行整合最终去调用原始的可调用对象。2. std::bind 的语法与占位符std::bind使用std::placeholders命名空间中的占位符如_1,_2来表示新生成函数的参数位置 。_1代表新函数的第一个参数_2代表第二个以此类推 。#includeiostream#includefunctionalusingnamespacestd;usingplaceholders::_1;usingplaceholders::_2;usingplaceholders::_3;intSub(inta,intb){return(a-b)*10;}intSubX(inta,intb,intc){return(a-b-c)*10;}classPlus{public:doubleplusd(doublea,doubleb){returnab;}};intmain(){// 1. 调整参数顺序// _2 代表 sub2 被调用时的第二个参数_1 代表第一个参数// 当执行 sub2(10, 5) 时参数映射为 Sub(5, 10)autosub2bind(Sub,_2,_1);coutsub2(10,5)endl;// 2. 调整参数个数固定参数/偏函数应用// 绑死第一个参数为 100生成一个只需要一个参数的新函数autosub3bind(Sub,100,_1);coutsub3(5)endl;// 映射为 Sub(100, 5)autosub4bind(Sub,_1,100);coutsub4(5)endl;// 映射为 Sub(5, 100)// 对于多参函数可以任意绑死某几个参数autosub5bind(SubX,100,_1,_2);coutsub5(5,1)endl;// SubX(100, 5, 1)autosub6bind(SubX,_1,100,_2);coutsub6(5,1)endl;// SubX(5, 100, 1)autosub7bind(SubX,_1,_2,100);coutsub7(5,1)endl;// SubX(5, 1, 100)// 3. 配合 std::function 绑死类成员函数的 this 指针// 将对象 Plus() 作为隐藏的 this 指针绑死在第一个参数位置// 这样成员函数就可以像普通函数一样被包装为只需要两个 double 参数的 functionfunctiondouble(double,double)f7bind(Plus::plusd,Plus(),_1,_2);coutf7(1.1,1.1)endl;return0;}关键点说明bind绑定类对象时如Plus()通常是值拷贝。如果需要引用绑定需要使用std::ref或直接传递对象的指针。使用bind将成员函数的this参数固定后极大地简化了其在回调函数、事件机制中的调用接口。三、 利用 bind 实现参数柯里化柯里化:将多参数函数转换为一系列单参数函数的技术使得函数可以逐步接收参数并支持参数复用和函数组合。std::bind在工程实践中常用于降低函数的调用维度。例如将一个通用的计算函数通过绑定固定参数特化为特定业务场景的具体函数。#includeiostream#includefunctionalusingnamespacestd;usingplaceholders::_1;intmain(){// 基础计算模型计算指定利率、本金、年限下的复利净利润autofunc1[](doublerate,doublemonty,intyear)-double{doubleretmonty;for(inti0;iyear;i){retret*rate;}returnret-monty;};// 业务场景特化将基础计算模型包装为单参数的特定理财产品计算器// 绑死利率(参数1)和年限(参数3)只保留本金(参数2)作为占位符 _1 接收输入functiondouble(double)func3_1_5bind(func1,0.015,_1,3);// 1.5%利率3年期functiondouble(double)func5_1_5bind(func1,0.015,_1,5);// 1.5%利率5年期functiondouble(double)func10_2_5bind(func1,0.025,_1,10);// 2.5%利率10年期functiondouble(double)func20_3_5bind(func1,0.035,_1,30);// 3.5%利率30年期// 调用特化后的函数逻辑更加清晰接口更加简洁coutfunc3_1_5(1000000)endl;coutfunc5_1_5(1000000)endl;coutfunc10_2_5(1000000)endl;coutfunc20_3_5(1000000)endl;return0;}通过这种方式底层复杂的通用接口被解耦并转化为更高层、更具体的业务接口这也是函数式编程思维在 C 中的具体体现。四、 核心总结std::function的核心在于类型统一解决了模板函数因接收不同可调用类型而导致的实例化膨胀问题 。非静态成员函数在被包装时由于包含隐藏的this指针必须显式传递对象或指针参数。std::bind的核心在于接口适配通过内部生成仿函数并映射参数位置可以调整函数参数的顺序、固定部分参数或是抹平类成员函数的对象依赖 。返回的未命名类型通常使用auto接收或转换并赋值给签名匹配的std::function对象。

相关新闻

Gopeed下载器终极指南:全平台多协议高速下载解决方案

Gopeed下载器终极指南:全平台多协议高速下载解决方案

Gopeed下载器终极指南:全平台多协议高速下载解决方案 【免费下载链接】gopeed A fast, modern download manager for HTTP, BitTorrent, Magnet, and ed2k. Cross-platform, built with Golang and Flutter. 项目地址: https://gitcode.com/GitHub_Trending/go/g…

2026/7/29 13:02:40阅读更多 →
STM32 OLED动态显示实现:从静态到流畅动画的进阶指南

STM32 OLED动态显示实现:从静态到流畅动画的进阶指南

1. 项目概述:让STM32的OLED屏“活”起来玩过STM32的朋友,手里大概率都躺着一块0.96寸或1.3寸的OLED屏。这玩意儿功耗低、对比度高,是嵌入式开发里最经典的显示外设之一。但很多人对它的使用,还停留在显示几行静态文字、画个简单图…

2026/7/29 13:02:39阅读更多 →
Android USB打印开发实战:从Host模式到ESC/POS指令全解析

Android USB打印开发实战:从Host模式到ESC/POS指令全解析

1. 项目缘起:当Android设备需要“开口说话”在移动开发领域,我们常常聚焦于网络通信、UI交互、数据存储这些“显学”。但有一类需求,它连接着数字世界与物理世界,却因为相对小众而被许多开发者忽略,那就是Android设备通…

2026/7/29 13:02:39阅读更多 →
西门子840D HMI ADVANCED PC版数控系统详解

西门子840D HMI ADVANCED PC版数控系统详解

1. 西门子840D HMI ADVANCED FOR PC系统概述西门子840D HMI ADVANCED FOR PC是西门子公司针对数控系统开发的一款人机界面软件解决方案。作为工业自动化领域的标杆产品,它主要服务于840D数控系统,但通过灵活的配置也能兼容810D和840DSL等系列数控系统。这…

2026/7/29 16:45:30阅读更多 →
人机协作新范式:盘点2026年当红之选的AI论文写作软件

人机协作新范式:盘点2026年当红之选的AI论文写作软件

深夜对着空白的文档,文献散落一地,导师的deadline步步紧逼——这场景,每个写过论文的人都懂。别焦虑了,2026年的AI论文写作工具,已经能帮你从选题到查重,实现全流程的智能辅助。经过对多款主流工具的深度实…

2026/7/29 16:45:30阅读更多 →
Spring AI与Milvus构建企业级RAG架构实战

Spring AI与Milvus构建企业级RAG架构实战

1. 项目概述:当RAG遇上企业级需求 去年在金融行业落地知识库项目时,我亲历了大模型"幻觉"带来的灾难——某次系统将"年化收益率3.5%"错误回答成"35%",差点引发客户投诉。这正是我们选择Spring AI Milvus技术栈…

2026/7/29 16:45:30阅读更多 →
天津geo优化公司哪家服务好?广拓时代谈GEO效果验收

天津geo优化公司哪家服务好?广拓时代谈GEO效果验收

开篇先说结论:围绕“天津geo优化公司哪家服务好”做判断,不能只看搜索结果里的公司名字,更要看服务商是否能把AI可见度、内容信源、数据复盘和企业真实资料统一起来。效果验收。 一、验收标准不清,服务好坏就说不清 企业问天津geo…

2026/7/29 16:45:30阅读更多 →
Arduino声控灯制作:从传感器原理到智能控制实践

Arduino声控灯制作:从传感器原理到智能控制实践

1. 项目概述与核心思路 声控灯,听起来像是智能家居里一个很酷的小玩意儿,但其实它的核心原理并不复杂。简单来说,就是让一个“耳朵”(声音传感器)去听环境里的动静,当它听到足够大的声音时,就告…

2026/7/29 16:45:30阅读更多 →
网站日志分析SEO问题方法:僵尸页面筛查,节省70%抓取额度

网站日志分析SEO问题方法:僵尸页面筛查,节省70%抓取额度

每天有上万次访问请求涌入服务器,其中百分之七十消耗在从未被真实用户打开过的深层网页上。搜索引擎蜘蛛访问独立站点时,单日分配的抓取频次受到服务器响应时间与站点权重的双重限制。多数企业主将精力集中在关键词布局与外部链接数量上,却忽…

2026/7/29 16:43:30阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“!

28. Agent 执行到一半想暂停?用 interrupt 给它设个“关卡“! 在构建复杂的 Agent 系统时,我们经常会遇到这样的场景:Agent 正在执行一个多步骤的任务,比如“下单购买商品”,但执行到一半时,我们…

2026/7/29 0:01:46阅读更多 →
自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

自律同行,突破无界!NANK南卡正式官宣曾舜晞成为品牌代言人

近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…

2026/7/29 0:01:46阅读更多 →
【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

【RT-DETR多模态创新改进】CVPR 2025 | 独家特征融合创新改进篇 | 引入RLAB残差线性注意力模块,有效融合并强调多尺度特征,多种改进点,适合红外与可见光融合目标检测任务,有效涨点

一、本文介绍 🔥本文在RT-DETR多模态融合目标检测中引入RLAB残差线性注意力模块,可在不同模态特征交互阶段进行多次残差细化,使可见光、红外等特征在尺度、语义和空间位置上更好对齐;随后将细化特征与解码器输出拼接并生成Q、K、V,通过线性注意力自适应强化关键通道、目…

2026/7/29 0:01:46阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/28 20:22:24阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/29 4:31:51阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/29 14:26:42阅读更多 →