欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > 【C++11】包装器:function 和 bind

【C++11】包装器:function 和 bind

2025/5/1 10:26:43 来源:https://blog.csdn.net/tan_run/article/details/147599882  浏览:    关键词:【C++11】包装器:function 和 bind

📝前言:
这篇文章我们来讲讲C++11——包装器:functionbind,对于每个包装器主要讲解:

  1. 原型
  2. 基本语法
  3. 使用示例

🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏,Linux


文章目录

  • 一,function
    • function原型
    • function基本语法
    • function使用示例
  • 二,bind
    • bind原型
    • bind基本语法
    • bind使用示例

一,function

function原型

function原型

template <class T>
class function; // undefined
template <class Ret, class... Args>
class function<Ret(Args...)>;
  • function是一个类模板,是一个包装器。在<functional>头文件中
  • function的实例化对象可以包装存储其他的可以调用对象,如函数指针、仿函数、 lambda 、 bind 表达式等。
  • 存储的可调⽤对象被称为std::function的⽬标。若std::function不含⽬标,则称它为空。调⽤空std::function的⽬标导致抛出std::bad_function_call 异常

function基本语法

基本语法

包装时:

function<callable_ret(arg_list)> newCallable = callable;

使用时:

newCallable((arg_list); // 这样来调用可调用对象
  • 包装静态成员函数:要指定类域并且前面加&才能获取地址
  • 包装普通成员函数:也要指明类域和&。并且,参数列表要多一个参数:传 对象 或 对象指针(因为普通成员函数还有一个隐含的this指针参数)

function使用示例

示例:

#include<functional>
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()
{// 包装各种可调用对象function<int(int, int)> f1 = f;function<int(int, int)> f2 = Functor();function<int(int, int)> f3 = [](int a, int b) {return a + b; };cout << f1(1, 1) << endl;cout << f2(1, 1) << endl;cout << f3(1, 1) << endl;// 包装静态成员函数// 成员函数要指定类域并且前面加&才能获取地址function<int(int, int)> f4 = &Plus::plusi;cout << f4(1, 1) << endl;// 包装普通成员函数// 普通成员函数还有一个隐含的this指针参数,所以绑定时传对象或者对象的指针过去都可以function<double(Plus*, double, double)> f5 = &Plus::plusd;Plus pd;cout << f5(&pd, 1.1, 1.1) << endl;function<double(Plus, double, double)> f6 = &Plus::plusd;cout << f6(pd, 1.1, 1.1) << endl;cout << f6(pd, 1.1, 1.1) << endl;function<double(Plus&&, double, double)> f7 = &Plus::plusd;cout << f7(move(pd), 1.1, 1.1) << endl;cout << f7(Plus(), 1.1, 1.1) << endl;return 0;
}

作用:把不同的可调用对象包装起来,方便统一方式的调用。

二,bind

bind原型

bind原型

simple(1)
template <class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
with return type (2)
template <class Ret, class Fn, class... Args>
/* unspecified */ bind (Fn&& fn, Args&&... args);
  • bind 是⼀个函数模板,它也是⼀个可调⽤对象的包装器,可以把他看做⼀个函数适配器
  • 对接收的fn可调用对象进行处理后返回⼀个可调用对象(本质是返回一个仿函数对象)
  • bind 也在<functional>这个头⽂件中
  • 对于获取静态成员变量和普通成员变量也都要指明类域和&
  • 常见的用法: bind 可以用来调整参数个数和参数顺序

bind基本语法

基本语法

包装时:

auto newCallable = bind(callable,arg_list); 

使用时:

newCallable(arg_list);

当我们调⽤newCallable时,newCallable会调⽤callable,并传给它arg_list中的参数。

arg_list中的参数

  • args_list中用placeholders::_n占位符(_n这个占位符在placeholders这个命名空间里面),或直接传具体的值来进行和参数的绑定
  • 数值n表示⽣成的可调用对象中参数的位置:_1newCallable的第⼀个参数,_2为第⼆个参数,以此类推。【即:第一个实参会被传到_1这个位置,第二个会被传到_2

bind使用示例

示例:

#include<functional>
using placeholders::_1;
using placeholders::_2;
using placeholders::_3;
int Sub(int a, int b)
{return (a - b) * 10;
}
int SubX(int a, int b, int c)
{return (a - b - c) * 10;
}
class Plus
{
public:static int plusi(int a, int b){return a + b;}double plusd(double a, double b){return a + b;}
};
int main()
{auto sub1 = bind(Sub, _1, _2);cout << sub1(10, 5) << endl;// 改变参数位置顺序auto sub2 = bind(Sub, _2, _1);cout << sub2(10, 5) << endl;// 调整参数个数(常用)auto sub3 = bind(Sub, 100, _1);cout << sub3(5) << endl;auto sub4 = bind(Sub, _1, 100);cout << sub4(5) << endl;// 分别绑死第123个参数auto sub5 = bind(SubX, 100, _1, _2);cout << sub5(5, 1) << endl;auto sub6 = bind(SubX, _1, 100, _2);cout << sub6(5, 1) << endl;auto sub7 = bind(SubX, _1, _2, 100);cout << sub7(5, 1) << endl;// 成员函数对象进行绑死,就不需要每次都传递了function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2);cout << f7(1.1, 1.1) << endl;
}

绑定关系解析:

在这里插入图片描述
附带参数位置交换的绑定:
在这里插入图片描述


🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词