📝前言:
这篇文章我们来讲讲C++11------包装器:function
和bind
,对于每个包装器主要讲解:
- 原型
- 基本语法
- 使用示例
🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏,Linux
文章目录
一,function
function原型
function
原型:
cpp
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基本语法
基本语法:
包装时:
cpp
function<callable_ret(arg_list)> newCallable = callable;
使用时:
cpp
newCallable((arg_list); // 这样来调用可调用对象
- 包装静态成员函数:要指定类域并且前面加
&
才能获取地址 - 包装普通成员函数:也要指明类域和
&
。并且,参数列表要多一个参数:传 对象 或 对象指针(因为普通成员函数还有一个隐含的this
指针参数)
function使用示例
示例:
cpp
#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
原型:
cpp
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基本语法
基本语法:
包装时:
cpp
auto newCallable = bind(callable,arg_list);
使用时:
cpp
newCallable(arg_list);
当我们调⽤newCallable
时,newCallable
会调⽤callable
,并传给它arg_list
中的参数。
arg_list
中的参数:
args_list
中用placeholders::_n
占位符(_n
这个占位符在placeholders
这个命名空间里面),或直接传具体的值来进行和参数的绑定- 数值
n
表示⽣成的可调用对象中参数的位置:_1
为newCallable
的第⼀个参数,_2
为第⼆个参数,以此类推。【即:第一个实参会被传到_1
这个位置,第二个会被传到_2
】
bind使用示例
示例:
cpp
#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;
}
绑定关系解析:

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