C++11 包装器

1.function包装器

1.1 概念介绍

ret = func(x);
上面 func 是什么呢?那么 func 可能是函数名,函数指针,函数对象 ( 仿函数对象 ), 也可能是lamber 表达式对象,这些都是可调用的类型。

函数包装器,也称为函数适配器或函数封装器,是一种编程模式,用于将函数或对象包装在另一层抽象中,以改变其调用签名或行为。C++中的function本质是一个类模板,也是一个包装器。其包含在头文件<functional>。function可以把这些所有参数类型和返回值类型相同的可调用类型(函数指针,仿函数对象,lamber表达式对象),统一的管理起来,让它们都变成一个类型。

1.2 语法使用

function类原型:

模板参数说明:
Ret : 被调用函数的返回类型
Args… :被调用函数的形参
使用如下:
#include<iostream>
#include <functional>
using namespace std;
int f(int a, int b)
{
	return a + b;
}
struct Functor
{
public:
	int operator() (int a, int b)
	{
		return a + b;
	}
};
int main()
{
	// 函数名(函数指针)
	function<int(int, int)> func1 = f;
	cout << func1(1, 2) << endl;
	// 函数对象
	function<int(int, int)> func2 = Functor();
	cout << func2(1, 2) << endl;
	// lamber表达式
	function<int(int, int)> func3 = [](int a,int b)
	{return a + b; };
	cout << func3(1, 2) << endl;
	return 0;
}

在上述代码中,f函数,Functor仿函数,以及lambda表达式,它们的返回值都是int,参数类型也是int,int,因此可以经过包装器包装为function<int(int,int)>而变为同一类型,这样就可以统一管理了。

1.3 function包装类的成员函数

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)> func4 = &Plus::plusi;
	cout << func4(1, 2) << endl;
	//用法一
	function<double(Plus, double, double)> func5 = &Plus::plusd;
	cout << func5(Plus(), 1.1, 2.2) << endl;
	//用法二
	function<double(Plus*, double, double)> func6 = &Plus::plusd;
	Plus tmp;
	cout << func6(&tmp, 1.1, 2.2) << endl;
	return 0;
}

在使用function包装类的成员函数时需要注意,类的非静态成员函数参数中天然包含了一个该类指针参数,即this指针。所以我们包装时需要在function参数列表中也加上该类指针或者该类,实例化时也同理。

1.4 实例应用

int evalRPN(vector<string>& tokens) {
	map<string, function<int(int, int)>> opfunc = {
		{"+",[](int x,int y) { return x + y; }},
		{"-",[](int x,int y) { return x - y; }},
		{"*",[](int x,int y) { return x * y; }},
		{"/",[](int x,int y) { return x / y; }},
	};
	stack<int> q;
	for (auto& e : tokens)
	{
		if (e == "+" || e == "-" || e == "*" || e == "/")
		{
			int num1 = q.top();
			q.pop();
			int num2 = q.top();
			q.pop();
			q.push(opfunc[e](num2, num1));
		}
		else
		{
			q.push(stoi(e));
		}
	}
	return q.top();
}

2.bind包装器

2.1 概念介绍

std::bind是C++11中引入的一个函数适配器,它允许您绑定函数或函数对象的一部分参数,从而创建一个新的可调用实体。std::bind的定义位于<functional>头文件中。它的基本用途是将一个函数与其参数一起进行绑定,生成一个新的函数对象,这个新对象可以在不同的上下文中被调用,而不需要再次提供那些已经绑定的参数。

2.2 语法使用

第一个参数为可调用对象,后续参数为该可调用对象的参数。其后续参数的语法比较特别,C++11后新增一个命名空间域placeholders,其内部会存储很多变量,这些变量用于函数的传参,变量的名字为_x,表示第x个参数。例如_1可调用对象的第一个参数,_2为第二个参数。

使用如下:

using namespace placeholders;
int Plus(int a, int b)
{
	return a + b;
}
class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};
int main()
{
	//表示绑定函数plus 参数分别由调用 func1 的第一,二个参数指定,将placeholders空间
	//展开后即可直接使用_x.
	function<int(int, int)> func1 = bind(Plus, placeholders::_1,_2);
	//func2的类型为 function<int(int, int)> 与func1类型一样
	//表示绑定函数 plus 的第一,二为: 10, 20,即可不用传参
	auto  func2 = bind(Plus, 10, 20);
	// 参数调换顺序
	auto Div = [](int a, int b) { return a / b; };
	auto func3 = bind(Div, _2, _1);
	cout << func1(1, 2) << endl;
	cout << func2() << endl;
	cout << func3(20, 60);
	return 0;
}

一般而言,我们用bind函数可以把一个原本接收N个参数的函数fn,通过绑定一些参数,返回一个接收M个(M 可以大于N,但这么做没什么意义)参数的新函数。同时,使用bind函数还可以实现参数顺序调整等操作。

2.3 function包装类的成员函数

class Sub
{
public:
	int sub(int a, int b)
	{
		return a - b;
	}
};
int main()
{
	Sub s;
	function<int(int, int)> func4 = bind(&Sub::sub, s, _1, _2);
	cout << func4(1, 2) << endl;
	return 0;
}

在使用bind包装类的成员函数时需要注意,类的非静态成员函数参数中天然包含了一个该类指针参数,即this指针。所以我们包装时需要在bind参数列表中也加上该类指针或者该类,实例化时也同理。

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我要满血复活

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值