C++沉思录读书笔记(21,22章)- 函数对象存在的意义以及自定义能应用bind1st(bind2nd)的函数对象模板

函数对象存在的意义

        假设有一个类型为vector<int>的对象,我们想找出其中第一个大于100的元素对应的迭代器,显然我们可以使用如下方法

find_if(v.begin(), v.end(), greater100);

          其中greater100是一个函数指针,这个指针对应的函数定义如下

bool greater100(int n)
{
	return n > 1000;
}

         上述功能实现非常简单,我们使用函数指针就轻松解决了问题,但如果新的需求来了,比如我们还想找出第一个大于100的元素,那我们必须新定义一个新的函数,在这种情况下,一旦新的需求出现,我们必须新定义一个相似却不相同的函数

       这太麻烦了,C++中解决这类问题的办法是使用函数对象,这个解决方法相当优雅高效,代码如下:

find_if(v.begin(), v.end(),bind2nd(greater<int>(), x) //设置好需要的x的值即可


自定义能应用bind1st和bind2nd的函数对象模板
bind1st和bind2nd的概念
bind1st和bind2nd是库类模板,它们有个有趣的特性,能将某个值绑定到一个二元函数对象的一个参数之上,例如
bind1st(f, x)将生成一个与f类型一直的函数对象F,并且F(y)的返回值等于f(x,y)的返回值
bind2nd(f, y)将生成一个与f类型一直的函数对象F,并且F(x)的返回值等于f(x,y)的返回值


先来看看预定义函数符的源码,在头文件functional能找到如下代码(VS):

template<class _Ty>
	struct greater
		: public binary_function<_Ty, _Ty, bool>
	{	// functor for operator>
	bool operator()(const _Ty& _Left, const _Ty& _Right) const
		{	// apply operator> to operands
		return (_Left > _Right);
		}
	};
//预定义函数符的基类
template<class _Arg1,
	class _Arg2,
	class _Result>
	struct binary_function
	{	// base class for binary functions
	typedef _Arg1 first_argument_type;
	typedef _Arg2 second_argument_type;
	typedef _Result result_type;
	};
          我们自定义的函数对象模板依葫芦画瓢即可,在后面的实例代码中我自定义了一个Plus函数对象模板

        按照上面这种形式定义的函数对象模板都定义了成员first_argument_type,second_argument_type和result_type,实际中这些成员都是放在一个基类模板binary_function中,它们的作用不不言而喻;这几个成员的定义与函数对象需要与函数对象模板bind1st和bind2nd需要进行配合有关,比如bind1st类模板的大致框架如下:

template<T> //仅为说明原理,具体VS的C++库中的源码与此不同
class bind1st
{
	bind1st(const T&, const T::first_argument_type&);
	T::result_type operator() (const T::second_argument_type);
	//...
}
自定义Plus函数对象模板的完整示例代码如下:

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

template <class T>
class Plus: public binary_function<T,T,T>
{
public:
	const T& operator()(const T& n1, const T& n2) const
	{ return n1 + n2; }

};

void main()
{
	Plus<int> a;
	cout << a(1,2) << endl;

	binder1st<Plus<int> > c = bind1st(a,2);  //验证与bind1st结合有效性
	cout << c(2) << endl;

	Plus<int>::result_type i = 5;  //验证是否result_type等的存在
	cout << i << endl;
}
运行结果如下:

3
4
5



你可能感兴趣的:(C++沉思录读书笔记(21,22章)- 函数对象存在的意义以及自定义能应用bind1st(bind2nd)的函数对象模板)