包装器是一种调用类型,本质是类模板。
意义:
C++中,函数可以有多种实现方法,除了直接实现函数还可以用仿函数和lambda还有类的成员函数。包装器可以对这些调用类进行封装,简化。
使用:
function <返回值类型(参数列表)> 变量名
样例:?
#include<functional>
int add(int a, int b)
{
return a + b;
}
class mul
{
public:
int operator()(int a, int b)
{
return a * b;
}
};
class Sub
{
public:
int sub(int a,int b)
{
return a - b;
}
}
int main()
{
function<int(int, int)> f1 = add;
function<int(int, int)> f2 = mul();
function<int(int, int)> f3 = [](int a, int b) {return a / b; };
function<int(int, int)> f4 = &Sub::sub;//用成员函数地址&
cout << f1(2, 3) << endl;
cout << f2(2, 3) << endl;
cout << f3(2, 3) << endl;
cout << f4(2, 3) << endl;
return 0;
}
使用vector,将所有函数放到一个vector中,类似于函数指针数组:
#include<functional>
double add(double a, double b) { return a + b; }
double sub(double a, double b) { return a - b; }
class mul
{
public:
int operator()(int a, int b)
{
return a * b;
}
};
int main()
{
map<string, function<double(double, double)>> fun;
fun["+"] = add;
fun["-"] = sub;
fun["*"] = mul();
fun["/"] = [](double a, double b) {return a / b; };
return 0;
}
bind可以针对原函数参数列表做调整,生成一个新的函数。
形式:
auto newcallable = bind(callable, args_list)
placeholders在args_list中的位置对应原函数参数的位置;调用fbind函数中的参数依次按照placeholders的顺序传递
普通函数,仿函数和lambda的绑定:
#include<functional>
int main()
{
map<string, function<double(double, double)>> fun;
fun["-"] = [](double a, double b) {a - b; };
auto fbind1 = bind(fun["-"], placeholders::_1, placeholders::_2);
auto fbind2 = bind(fun["-"], placeholders::_2, placeholders::_1);//参数调换顺序
cout << fbind1(2, 3) << endl;
cout << fbind2(2, 3) << endl;
auto fbind3 = bind(fun["-"], 10, placeholders::_1);//指定第一个参数
cout << fbind3(6) << endl;
return 0;
}
注:fbind2: 2->placeholders::_1->b? ? ? ? 3->placeholders::_2->a? ? ? ? 结果是:3-2
类的成员函数的绑定
class Plus
{
public:
static int plusi(int a, int b)
{
return a + b;
}
double plusd(double a, double b)
{
return a + b;
}
};
int main()
{
//静态成员函数在类定义后就会生成,储存在公共代码段
function<int(int, int)> fun1 = bind(&Plus::plusi, placeholders::_1, placeholders::_2);
//绑定非静态成员函数,需要先实例化一个对象,因为非静态成员函数只有实例化的时候才会生成才有地址
Plus p;
function<int(int, int)> fun2 = bind(&Plus::plusd, p, placeholders::_1, placeholders::_2);
return 0;
}