C++11:包装器

目录

1.function包装器

2.bind包装器


1.function包装器

        C++是面向对象的一门语言,因此为了封装函数,也出现了仿函数,便于传参使用。C++11新增了lambda表达式,进一步提高编程者的效率。但是,C语言的函数指针、C++98的仿函数、C++11的lambda表达式都存在一些弊端:

函数指针void(*pf)()类型复杂,不便于阅读书写
仿函数不同的类,类型不同
lambda表达式语法层没有返回类型

            比如这部分代,有一个函数模板,分别用不同的形式去传参,模板实例化的useF是有三种

template<class F,class T>
T useF(F fun, T x)
{
	static int count = 0;
	cout << "count:" << ++count << endl;

	cout << "------------" << endl;
	return fun(x);
}
//回调函数
double f(double i)
{
	return i / 2;
}
//仿函数
struct Functor
{
	double operator()(double d)
	{
		return d / 3;
	}
};
int main()
{
	//函数指针
	cout << useF(f, 11.11) << endl;
	//仿函数
	cout << useF(Functor(), 11.11) << endl;
	//lambda表达式
	cout << useF([](double d)->double {return d / 4; }, 11.11) << endl;

	return 0;
}

        C++11为了统一类型,对这一层进行了封装,即包装器。


        C++的头文件<functional>中存在类模板function

 

         

模板参数说明:
Ret: 被调用函数的返回类型
Args…:被调用函数的形参

        有了包装器,对上面的语法修改:

int main()
{
	//函数指针
	function<double(double)> func1 = f;//这一层用包装器
	cout << useF(func1, 11.11) << endl;//此时useF的第一个参数都是function类型

	//仿函数
	function<double(double)> func2 = Functor();
	cout << useF(func2, 11.11) << endl;
	//lambda表达式
	function<double(double)> func3 = [](double d)->double {return d / 4; };
	cout << useF(func3, 11.11) << endl;

	return 0;
}

        特殊情况用包装器封装类中的成员函数。

int main()
{
	// 普通函数
	function<int(int, int)> fc1 = f;
	cout << fc1(1, 1) << endl;

	// 静态成员函数
	function<int(int, int)> fc2 = Plus::plusi;
	cout << fc2(1, 1) << endl;

	// 因为this指针导致参数不匹配,非静态成员函数需要对象的指针或者对象去进行调用
	/*第一种写法:
	Plus plus;
	function<double(Plus*, double, double)> fc3 = &Plus::plusd;
	cout << fc3(&plus, 1, 1) << endl;*/
	
	//第二种写法
	function<double(Plus, double, double)> fc3 = &Plus::plusd;
	cout << fc3(Plus(), 1, 1) << endl;

	return 0;
}

2.bind包装器

        bind是定义在C++头文件<functional>中的函数模板

 

        使用bind一般可以调整函数参数的顺序或者调整个数。 调整个数的场景居多,拿这个举例。

实现的大致方法是用特定的顺序绑定参数。

在C++的头文件<functional>中封装了一个命名空间placeholders

        _1、_2、_3·····就是用来绑定参数的标识符。

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<double(double, double)> fc4 = bind(&Plus::plusd, Plus(), placeholders::_1, placeholders::_2);
	cout << fc4(2, 3) << endl;

	function<double(double)> fc5 = bind(&Plus::plusd, Plus(), placeholders::_1, 20);
	cout << fc5(2) << endl;

	return 0;
}

         bind的第一个参数,是函数名,这里由于是成员函数,要加&取地址符(语法规定)。剩下的参数都是属于参数包的,由于this指针,这里第二个参数对应plusd隐藏的第一个参数。_1绑定plusd的a,_2绑定b。

        

        也可以只绑定a,就是用_1来绑定,语法上要对应在正确的位置。 调用时,因为部分参数已经被绑定,因此明显减少了需要传递的参数:

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值