现在的位置: 首页 > 综合 > 正文

STL源码–函数对象

2014年01月12日 ⁄ 综合 ⁄ 共 3841字 ⁄ 字号 评论关闭

函数对象对于stl这个以迭代器为基石的库的重要性不言而喻

//函数对象的重要性不言而喻,尤其是对于stl这个以迭代器为基石的库

//定义一个函数对象,实现两数相加
template<class _Tp>
struct plus
{
	_Tp operator()(const _Tp& __x,const _Tp& __y){return __x+__y;}
};
//我们可以使用plus(x,y);
//假设我们需要的是-(x+y),怎么算?
template<class _Tp>
struct negative_plus
{
	_Tp operator()(const _Tp& __x,const _Tp& __y){return -(__x+__y);}
};
//对于这种非常简单的函数对象,我们可以重写,如果非常复杂的怎么办?这里就引出了配接器的概念,我们定义一个配接器
//它可以返回plus(x,y)的负数,当然它的参数就是plus函数对象:
template<class _Func>
struct negate
{
	//参数是什么?返回值是什么类型?怎么由plus对象得到_Tp?
};
//上述的问题是配接器的普遍问题,怎么解决?


//诚然自己写的函数对象也可以用,但是,却不能与已定义好的函数对象很好的兼容,尤其是与配接器的兼容性。如果要写出
//兼容性好的,并且能使用配接器的函数对象,就要遵循规范:函数对象继承于下面的两个类!
//一元函数对象的基类:参数类型和返回结果类型
template<class _Arg,class _Result>
struct unary_function
{
	typedef _Arg argument_type;
	typedef _Result result_type;
};
//二元函数对象的基类
template<class _Arg1,class _Arg2,class _Result>
struct binary_function
{
	typedef _Arg1 first_argument_type;
	typedef _Arg2 second_argument_type;
	typedef _Result result_type;
};

//举个例子:
template<class _Tp>
struct plus :public binary_function<_Tp,_Tp,_Tp>
{
	_Tp operator()(const _Tp& __x,const _Tp& __y){return __x+__y;}
};

//配接器:
template<class _Function>
struct negate_binary:public binary_function<typename _Function::first_argument_type,
	  typename _Function::second_argument_type,typename _Function::result_type>
{
	explicit negate_binary(const _Function& __f):m_f(__f){}
	result_type operator()(const first_argument_type& __x,const second_argument_type& __y)const
	{return -(m_f(__x,__y));}
protected:
	_Function m_f;
};
//这样就可以实现各种类型的配接器了

//配接器类型二:将二元的函数对象转换为一元的函数对象,采用的方式是固定其中的一个参数,下面举例固定第一个参数
template<class _Function>
struct _bind1st:public unary_function<typename _Function::second_arugument_type,typename _Function::result_type>
{
protected:
	_Function m_function;
	typename _Function::first_arugument_type m_first;
public:
	 bind1st(const _Function& __f,const typename _Function::first_arugument_type& __x)
		:m_function(__f),m_first(__x){}
	result_type operator()(const argument_type& __y)const {return m_function(m_first,__y);}
};
//配接器类型三:组合函数对象,这是由简单的函数对象产生复杂函数对象的方法
//op1(op2(x)),op1(op2(x),op3(x)),op1(op2(x,y)),op1(op2(x),op3(y))四种,下面是第一种
//一元函数对象的组合:op1(op2(x))参数是op2的参数,结果是op1的结果
template<class _Function1,class _Function2>
struct compose1:public unary_function<typename _Function2::argument_type,typename _Function1::result_type>
{
protected:
	_Function1 m_function1;
	_Function2 m_function2;
public:
	compose(const _Function1& __f1,const _Function2& __f2)
		:m_function1(__f1),m_function2(__f2){}
	result_type operator()(const argument_type& __x) const{return m_function1(m_function2(__x));}
};

//至此,函数对象配接器的类型就结束了,但是stl为每个配接器都提供了一个函数使用接口,这个不知道为什么这样做。。
//例如:bind1st的函数接口:
template<class _Function>
inline _bind1st<_Function> bind1st(const _Function& __f,const typename _Function::first_argument_type& __x)
{return _bind1st<_Function>(__f,__x);}

//对于函数对象,有几个问题:
//1.函数指针,按理来说,对于用户,函数指针和函数对象的一样的,但是,stl中实现了很多将函数指针转化为函数对象的工具
//2,类成员函数的函数对象,这里是的使用方式是op(class),分四种情况:
//类成员函数有无参数?通过指针还是引用来调用?是否返回值?const还是non-const?
//举一例:
template <class _Ret, class _Tp>
class mem_fun_t : public unary_function<_Tp*,_Ret> {
public:
  explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}
  _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); }
private:
  _Ret (_Tp::*_M_f)();
};

template <class _Ret, class _Tp>
class const_mem_fun_t : public unary_function<const _Tp*,_Ret> {
public:
  explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
  _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); }
private:
  _Ret (_Tp::*_M_f)() const;
};


template <class _Ret, class _Tp>
class mem_fun_ref_t : public unary_function<_Tp,_Ret> {
public:
  explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) {}
  _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); }
private:
  _Ret (_Tp::*_M_f)();
};

template <class _Ret, class _Tp>
class const_mem_fun_ref_t : public unary_function<_Tp,_Ret> {
public:
  explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
  _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); }
private:
  _Ret (_Tp::*_M_f)() const;
};
//包装函数
template <class _Ret, class _Tp>
inline mem_fun_t<_Ret,_Tp> mem_fun(_Ret (_Tp::*__f)())
  { return mem_fun_t<_Ret,_Tp>(__f); }

抱歉!评论已关闭.