【C++】C++11的包装器:function与bind简介

【C++】C++11的包装器:function与bind简介

各位大佬好,我是落羽!一个坚持不断学习进步的学生。
如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步!
也欢迎关注我的blog主页:
落羽的落羽

文章目录

一、function

1. 概念

上一篇文章我们学习了lambda表达式的用法。

std::function是 C++11 标准库在 <functional> 头文件中引入的一个通用、多态的函数包装器。它的本质是一个类模板,可以包装、存储、复制和调用任何可调用对象(函数指针、仿函数、lambda表达式、bind表达式等),存储的可调用对象被称为function的目标。function不含目标则为空,调用空function的目标会抛异常。
函数指针、仿函数、lambda表达式等可调用对象的类型各不相同,function可以统一类型,对他们进行包装,这样在很多地方就方便声明可调用对象的类型。

2. 用法

在这里插入图片描述


以上是function的原型,使用语法为:

#include<functional> std::function<返回类型(参数类型1, 参数类型2,...)> 包装器名称;

来看一段代码实例:

#include<iostream>#include<functional>usingnamespace std;// 普通函数intadd(int a,int b){return a + b;}// Lambda表达式auto multiply =[](int a,int b){return a * b;};// 仿函数structSubtract{intoperator()(int a,int b)const{return a - b;}};intmain(){// 声明一个function,他可以包装一个返回int,接受两个int参数的可调用对象 function<int(int,int)> func;// 包装普通函数 func = add; cout <<"Add: "<<func(10,5)<< endl;// 输出 15// 包装 Lambda 表达式 func = multiply; cout <<"Multiply: "<<func(10,5)<< endl;// 输出 50// 包装仿函数对象 Subtract sub; func = sub; cout <<"Subtract: "<<func(10,5)<< endl;// 输出 5// 甚至可以包装一个临时的Lambda func =[](int a,int b){return a / b;}; cout <<"Divide: "<<func(10,5)<<std::endl;// 输出 2return0;}

有一个特殊的点是,类的成员函数也可以被包装,但成员函数必须要指定类域并且前面加上&才能获取地址,静态成员函数可以不加&,但是为了方便记忆,建议成员函数都加上吧。这时还有一个问题,普通成员函数还有一个隐含的this指针,在类外包装时,也一定要显式写出this指针参数类型,即当前类的指针类型:

classPlus{public:Plus(int n =10):_n(n){}staticintplusi(int a,int b){return a + b;}doubleplusd(double a,double b){return(a + b)* _n;}private:int _n;};intmain(){ function<int(int,int)> f =&Plus::plusi; cout <<f(1,1)<< endl;// 输出2 function<double(Plus*,double,double)> f1 =&Plus::plusd;//调用时实例化出一个对象取地址传参即可,或者传对象也可以 Plus pd cout <<f1(&pd,1.1,1.1)<< endl;// 输出22/*function<double(Plus, double, double)> f1 = &Plus::plusd; Plus pd cout << f1(pd, 1.1, 1.1) << endl; */return0;}

二、bind

1. 概念

std::bind是一个函数模板,也包含在<functional>中,是一个可调用对象的包装器,可以把他看做一个函数适配器,对接收的可调用对象处理后返回一个可调用对象。bind可以用来调整参数个数和参数顺序。

在这里插入图片描述

2. 用法

调用bind的一般形式为:auto newCallable = bind(callable, arg_list);其中newCallable本身是一个可调用对象,arg_list是一个用逗号分隔的参数列表,对应给定callable的参数。arg_list中的参数可能包含形如_n的占位符,n是一个正整数,它们占据了传递给newCallable的参数的位置。n表示生成的可调用对象的参数的位置:如_1为newCallable的第1个参数,_2为newCallable的第2个参数,_3为newCallable的第3个参数,以此类推,_1/_2/_3…这些占位符都在一个叫placeholders的命名空间中。

#include<functional>usingnamespace placeholders;intSub(int a,int b){return a - b;}intmain(){// _1代表sub1的第一个参数,_2代表sub1的第二个参数。// bind内写成_2, _1的顺序,意味sub1的第二个参数会传给Sub的第一个参数a,sub1的第一个参数会传给Sub的第二个参数bauto sub1 =bind(Sub, _2, _1); cout <<Sub(1,2)<< endl; cout <<sub1(1,2)<< endl;return0;}
在这里插入图片描述


这是只改变参数顺序的一般用法。

bind还有最常用的改变参数个数用法,这个用法一般是为了绑死某些参数,使之为一个固定值,使用时就不需要再传参:

#include<functional>usingnamespace placeholders;intSub(int a,int b){return a - b;}intmain(){// _1代表sub2的第一个参数,100代表绑死Sub的第一个参数a,a的值固定为100了// a的值固定了,传参时就不需要传给a,sub2的第一个参数就会传给Sub的第二个参数bauto sub2 =bind(Sub,100, _1); cout <<Sub(1,2)<< endl; cout <<sub2(1);return0;}
在这里插入图片描述

再比如,刚才上面讲到function包装类成员函数时说到,使用包装后的对象时还需要传给this指针一个参数。有了bind就可以提前绑死这个参数,后续每次使用就不需要额外传了:

#include<functional>usingnamespace placeholders;classPlus{public:Plus(int n =10):_n(n){}doubleplusd(double a,double b){return(a + b)* _n;}private:int _n;};intmain(){ function<double(double,double)> f =bind(&Plus::plusd,Plus(), _1, _2); cout <<f(1,2)<< endl;return0;}
在这里插入图片描述

本篇完,感谢阅读。

Read more

GitHub 44K 星!Skills:开源「智能体技能库」+ 手搓创建技能

2026年,AI的战场已从“回答问题”转向“完成任务”。 你是否想过: ✅ 能否让AI自动分析GitHub仓库并提交PR? ✅ 能否让AI读完一篇论文后,自动生成PPT并邮件发送给团队? ✅ 能否让AI在发现线上Bug后,自动回滚版本并通知运维? 这些不再是幻想—— 一个名为 Skills 的开源项目,正在让AI智能体(Agent)真正拥有“做事”的能力 。 此仓库包含Anthropic为Claude实现的技能。 截至2026年1月,该项目已在GitHub收获 44,000+ Stars ,被Hugging Face、LangChain、LlamaIndex等主流框架深度集成,被誉为 “AI智能体的操作系统级技能库” 。 今天,我们就来揭开它的神秘面纱。  什么是Skills? Skills (全名: )是一个 开放、模块化、可组合的智能体技能仓库 。 它的核心理念很简单: “不要让AI从零开始学做事,而是给它一套标准化的‘技能工具箱’。” 就像人类通过学习“开车”“做饭”“写代码”来完成复杂任务,

By Ne0inhk

git2.53.0安装步骤

⭐ 一、安装(核心选项直接抄) 安装界面选择建议核心原因组件选择✅ 保留默认勾选,取消 Check daily for updates自动更新没必要,核心功能够用默认编辑器✅ 选 Use Visual Studio Code as Git's default editor避免 Vim 学习成本,和开发工具统一初始分支名✅ 选 Override,分支名填 main适配 GitHub/Gitee 主流规范PATH 配置✅ 选 Git from the command line and also from 3rd-party software多终端可用(Git Bash/CMD/VSCode)SSH 客户端✅

By Ne0inhk
GitHub访问加速全攻略:开发者必备的5种提速方案(亲测有效)!!!

GitHub访问加速全攻略:开发者必备的5种提速方案(亲测有效)!!!

文章目录 * 一、为什么GitHub这么慢?(先搞懂原理) * 1.1 网络延迟的罪魁祸首 * 1.2 DNS污染问题 * 二、5大加速方案实测对比(附详细步骤) * 2.1 镜像站大法(新手首选) * 2.2 修改Hosts文件(永久生效) * 2.3 Git配置代理(程序员必备) * 2.4 使用Gitee中转(适合大项目) * 2.5 终极方案:GitHub加速器(黑科技) * 三、避坑指南(血泪经验) * 3.1 不要用盗版加速器! * 3.2 SSH连接比HTTPS更快 * 3.3 大文件用Git LFS * 四、速度测试对比(单位:

By Ne0inhk
GitHub介绍指南

GitHub介绍指南

作为程序员,GitHub 绝对是日常开发、技术成长、团队协作的核心工具——它不只是“代码仓库”,更是全球1亿+开发者的技术生态枢纽,从个人项目管理到大型团队协作,从开源学习到职场背书,吃透它能大幅提升开发效率、拓宽技术视野,是程序员不可或缺的“刚需装备”。 一、先厘清关键:GitHub ≠ Git(避免踩坑)        很多开发者初期会混淆两者,用两个通俗比喻就能快速区分,核心关系一句话概括:Git 负责“本地记录”,GitHub 负责“云端共享”: * Git:你本地电脑的“代码版本管理工具”(软件),无需联网,核心作用是记录代码每一次修改、管理分支、一键回退版本,相当于你私人的“代码日记本”,解决“改崩代码回不去”“多个最终版文件夹混乱”的痛点。 * GitHub:基于 Git 搭建的在线平台(网站),需联网使用,核心是将本地

By Ne0inhk