【C++】函数包装器

什么是函数包装器

简单来说函数适配器就是基于原有函数功能的基础上,再增加一些功能。

函数适配器就实现了这一功能:将一种函数对象转化为另外一种符合要求的函数对象。

STL函数适配器(FunctionAdapters)是工具,可以帮助你修改和组合函数对象,以便更方便地在STL算法中使用。

在STL标准库中,提供了一些函数包装的模板,它们可以对函数或者可调用的对象进行包装,方便在其他的函数中调用。

function

std::function是一个通用的多态函数封装器,它将一个可调用的对象,比如函数指针,函数对象,Lambda函数等,进行封装,方便在后续的代码中调用。

下图为模板类,R为函数返回类型,函数参数类型Args,class…说明是一个可变模板参数,代表模板可以接受任意多个参数。
0
要实例化一个这样的模板,并定义一个函数的包装器对象,可以使用这样的方式:

function<R(Args...)> fnname = target;

target是要封装的目标函数指针或者函数对象。

有了fnname对象,就可以通过调用它的重载的函数调用运算符,从而调用target函数。

代码示例

#include <functional>
#include <iostream>

double multiply(double a, double b)
{
	return a * b;
}

int main()
{
	std::function<double(double, double)> func1 = multiply;
	double res = func1(1.1, 2.3);
	std::cout << res << std::endl;
	return 0;
}

function也可以封装类的成员函数和成员变量

#include <functional>
#include <iostream>

struct Linear
{
	Linear(float k, float b) :k_(k),b_(b){}
	float f(float x) { return k_ * x + b_; }
	float k_, b_;
};

int main()
{
	//第一个参数是类引用,第二个开始才是成员函数参数类型
	std::function<float(Linear&, float)> mf = &Linear::f;
	Linear l(1.2, 2.3);		//先创建一个对象
	float res = mf(l, 5);	//使用my来调用类对象的函数
	std::cout << res << std::endl;

	//封装成员变量
	std::function<float(Linear&)> k = &Linear::k_;
	std::cout << k(l) << std::endl;
}

类型擦除模式

可以通过单个通用接口,来使用各种具体类型。

#include <map>
#include <functional>
#include <iostream>

using namespace std;

float add(float a, float b)
{
	return a + b;
}

struct Substract {
	float operator()(float a, float b) { return a - b; }
};

int main()
{
	map<char, function<double(double, double)>> calculator{
		{'+',add},
		{'-',Substract()},
		{'*',[](double a,double b)->double {return a * b; }}
	};
	cout << calculator['+'](12.0, 13) << endl;
	cout << calculator['-'](12.0, 13) << endl;
	cout << calculator['*'](12.0, 13) << endl;

	return 0;
}

bind

std::bind是个函数模板,它用来生成一个函数调用的转发包装器,也就是一个函数对象。调用这个包装器就相当于调用它所包装的函数或者对象f。
在这里插入图片描述

#include <iostream>
#include <functional>
using namespace std;

int sum(int a, int b, int c)
{
	cout << "a = " << a << " b = " << b << " c = " << c << endl;
	return a + b + c;
}

int main()
{
	//将sum,和参数1,2,3封装到函数对象中
	auto f = bind(sum, 1, 2, 3);
	int res = f();
	cout << "res = " << res << endl;
}
  • 也使用std::placeholders的占位符_1,_2,_3来代替被绑定的实际参数,这些参数可以调用函数对象时再传入实际的参数
#include <iostream>
#include <functional>
using namespace std;

int sum(int a, int b, int c)
{
	cout << "a = " << a << " b = " << b << " c = " << c << endl;
	return a + b + c;
}

int main()
{
	//使用std::placeholders的占位符_1,_2,_3来代替被绑定的实际参数,这些参数可以调用函数对象时再传入实际的参数
	auto f = std::bind(sum, 1, std::placeholders::_1, 3);
	int res = f(5);
	cout << "res = " << res << endl;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值