STL源码剖析(二十四)适配器之仿函数

functor adapters
functor adapters是所有适配器中数量最庞大的族群,包括bind、negate、compose,以及一般函数或成员函数的修饰。
通过绑定、组合、修饰能力,可无限制地创建出各种可能的表达式,搭配STL算法使用。
例,找出某个序列中所有不小于12的元素个数,可使用内建仿函数greater_equal,也可
not1(bind2nd(less<int>(), 12)),将less()的第二参数绑定为12,再加上否定操作,便形成不小于12的语意。
例,对序列中每个元素做特殊运算f(g(elem)),f, g都是数学函数,可替换为compose1(f(x), g(y)),假设对序列每个元素进行(v+2)*3的操作,令f(x)=x*3, g(y)=y+2,compose1(bind2nd(multiplies<int>(), 3), bind2nd(plus<int>(), 2))。注意:表达式会改变参数的值。

仿函数是将函数调用运算符重载的类,算法接受仿函数时,在执行过程中调用仿函数的operator(),STL同时提供了适配器使一般函数和成员函数可以与适配器或算法结合使用。
成员函数经mem_fun处理,一般函数经ptr_fun处理,未经处理的函数虽然可以函数指针形式传给算法,但没有适配能力。

辅助函数产生的实际效果
请添加图片描述

容器以类模板完成,算法以函数模板完成,仿函数则是将函数调用运算符重载的类模板,迭代器是将累加和取值操作符重载的类模板,适配器是应用于容器与迭代器上的类模板,应用于仿函数上的适配器如何事先对函数完成参数的绑定、执行结果的否定、多方函数的组合,就像容器适配器内藏一个底层容器,反向迭代器内藏一个正向迭代器,仿函数适配器也内藏了一个适配对象。
请添加图片描述

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Operation> //二元绑定类模板,绑定第一参数
    class binder1st //将二元仿函数转化为一元仿函数
    : public unary_function<typename _Operation::second_argument_type,
			    typename _Operation::result_type>
    {
    protected:
      _Operation op; //二元仿函数对象
      typename _Operation::first_argument_type value; //二元仿函数参数1

    public: //构造函数,接受二元仿函数对象,及参数1
      binder1st(const _Operation& __x,
		const typename _Operation::first_argument_type& __y)
      : op(__x), value(__y) { }

      typename _Operation::result_type //返回二元仿函数的返回类型
      operator()(const typename _Operation::second_argument_type& __x) const
      { return op(value, __x); } //第二参数为输入参数

      typename _Operation::result_type //函数调用运算符
      operator()(typename _Operation::second_argument_type& __x) const
      { return op(value, __x); } //调用二元仿函数,第一参数为绑定值
    } _GLIBCXX_DEPRECATED;

  template<typename _Operation, typename _Tp> //二元绑定函数模板
    inline binder1st<_Operation> //调用类模板,获得一元仿函数
    bind1st(const _Operation& __fn, const _Tp& __x)
    {
      typedef typename _Operation::first_argument_type _Arg1_type;
      return binder1st<_Operation>(__fn, _Arg1_type(__x));
    }

  template<typename _Operation> //二元绑定类模板,绑定第二参数
    class binder2nd //将二元仿函数转化为一元仿函数
    : public unary_function<typename _Operation::first_argument_type,
			    typename _Operation::result_type>
    {
    protected:
      _Operation op; //二元仿函数对象
      typename _Operation::second_argument_type value; //第二参数

    public: //构造函数,初始化二元仿函数对象及第二参数
      binder2nd(const _Operation& __x,
		const typename _Operation::second_argument_type& __y)
      : op(__x), value(__y) { }

      typename _Operation::result_type
      operator()(const typename _Operation::first_argument_type& __x) const
      { return op(__x, value); } //第一参数为输入参数

      typename _Operation::result_type //函数调用运算符
      operator()(typename _Operation::first_argument_type& __x) const
      { return op(__x, value); } //第二参数为绑定值
    } _GLIBCXX_DEPRECATED;

  template<typename _Operation, typename _Tp> //二元绑定函数模板
    inline binder2nd<_Operation> //调用类模板,获得二元仿函数
    bind2nd(const _Operation& __fn, const _Tp& __x)
    {
      typedef typename _Operation::second_argument_type _Arg2_type;
      return binder2nd<_Operation>(__fn, _Arg2_type(__x));
    } 


  template<typename _Predicate> //类模板
    class unary_negate //表示某一元仿函数的逻辑否定
    : public unary_function<typename _Predicate::argument_type, bool>
    {
    protected:
      _Predicate _M_pred; //一元仿函数对象

    public:
      explicit //构造函数,初始化一元仿函数对象
      unary_negate(const _Predicate& __x) : _M_pred(__x) { }

      bool //函数调用运算符
      operator()(const typename _Predicate::argument_type& __x) const
      { return !_M_pred(__x); } //返回一元仿函数调用后的否定
    };
    
  template<typename _Predicate> //函数模板,获得一元仿函数
    inline unary_negate<_Predicate>
    not1(const _Predicate& __pred)
    { return unary_negate<_Predicate>(__pred); } //调用类模板

  template<typename _Predicate> //类模板
    class binary_negate //表示某二元仿函数的逻辑否定
    : public binary_function<typename _Predicate::first_argument_type,
			     typename _Predicate::second_argument_type, bool>
    {
    protected:
      _Predicate _M_pred; //二元仿函数对象

    public:
      explicit //构造函数,初始化二元仿函数对象
      binary_negate(const _Predicate& __x) : _M_pred(__x) { }

      bool //函数调用运算符
      operator()(const typename _Predicate::first_argument_type& __x,
		 const typename _Predicate::second_argument_type& __y) const
      { return !_M_pred(__x, __y); } //返回二元仿函数调用后的否定
    };

  template<typename _Predicate> //函数模板,获得二元仿函数
    inline binary_negate<_Predicate>
    not2(const _Predicate& __pred)
    { return binary_negate<_Predicate>(__pred); } //调用类模板

  template<typename _Arg, typename _Result> //类模板
    class pointer_to_unary_function : public unary_function<_Arg, _Result> //将一般函数转换为一元仿函数
    {
    protected:
      _Result (*_M_ptr)(_Arg); //一元函数指针

    public:
      pointer_to_unary_function() { }

      explicit //构造函数,初始化函数指针
      pointer_to_unary_function(_Result (*__x)(_Arg))
      : _M_ptr(__x) { }

      _Result //函数调用运算符
      operator()(_Arg __x) const
      { return _M_ptr(__x); } //函数指针调用参数
    };

  template<typename _Arg, typename _Result>
    inline pointer_to_unary_function<_Arg, _Result>
    ptr_fun(_Result (*__x)(_Arg)) //函数模板,获得一元仿函数
    { return pointer_to_unary_function<_Arg, _Result>(__x); }

  template<typename _Arg1, typename _Arg2, typename _Result>
    class pointer_to_binary_function //将一般函数转换为二元仿函数
    : public binary_function<_Arg1, _Arg2, _Result>
    {
    protected:
      _Result (*_M_ptr)(_Arg1, _Arg2); //二元函数指针

    public:
      pointer_to_binary_function() { }

      explicit //构造函数,初始化函数指针
      pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2))
      : _M_ptr(__x) { }

      _Result //函数调用运算符
      operator()(_Arg1 __x, _Arg2 __y) const
      { return _M_ptr(__x, __y); } //函数指针调用参数
    };

  template<typename _Arg1, typename _Arg2, typename _Result>
    inline pointer_to_binary_function<_Arg1, _Arg2, _Result>
    ptr_fun(_Result (*__x)(_Arg1, _Arg2)) //函数模板,获得二元仿函数
    { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); }

  template<typename _Ret, typename _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<typename _Ret, typename _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<typename _Ret, typename _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<typename _Ret, typename _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<typename _Ret, typename _Tp, typename _Arg> //将成员函数转换为二元仿函数
    class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret>
    {
    public:
      explicit
      mem_fun1_t(_Ret (_Tp::*__pf)(_Arg))
      : _M_f(__pf) { }

      _Ret
      operator()(_Tp* __p, _Arg __x) const
      { return (__p->*_M_f)(__x); } //内部成员函数指针的调用

    private:
      _Ret (_Tp::*_M_f)(_Arg);
    };

  template<typename _Ret, typename _Tp, typename _Arg>
    class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret>
    {
    public:
      explicit
      const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const)
      : _M_f(__pf) { }

      _Ret
      operator()(const _Tp* __p, _Arg __x) const
      { return (__p->*_M_f)(__x); }

    private:
      _Ret (_Tp::*_M_f)(_Arg) const;
    };

  template<typename _Ret, typename _Tp, typename _Arg>
    class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
    {
    public:
      explicit
      mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg))
      : _M_f(__pf) { }

      _Ret
      operator()(_Tp& __r, _Arg __x) const
      { return (__r.*_M_f)(__x); } //内部成员函数的调用

    private:
      _Ret (_Tp::*_M_f)(_Arg);
    };

  template<typename _Ret, typename _Tp, typename _Arg>
    class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret>
    {
    public:
      explicit
      const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const)
      : _M_f(__pf) { }

      _Ret
      operator()(const _Tp& __r, _Arg __x) const
      { return (__r.*_M_f)(__x); }

    private:
      _Ret (_Tp::*_M_f)(_Arg) const;
    };

  template<typename _Ret, typename _Tp>
    inline mem_fun_t<_Ret, _Tp> 
    mem_fun(_Ret (_Tp::*__f)()) //获得一元仿函数
    { return mem_fun_t<_Ret, _Tp>(__f); }

  template<typename _Ret, typename _Tp>
    inline const_mem_fun_t<_Ret, _Tp>
    mem_fun(_Ret (_Tp::*__f)() const)
    { return const_mem_fun_t<_Ret, _Tp>(__f); }

  template<typename _Ret, typename _Tp>
    inline mem_fun_ref_t<_Ret, _Tp>
    mem_fun_ref(_Ret (_Tp::*__f)()) //获得一元仿函数
    { return mem_fun_ref_t<_Ret, _Tp>(__f); }

  template<typename _Ret, typename _Tp>
    inline const_mem_fun_ref_t<_Ret, _Tp>
    mem_fun_ref(_Ret (_Tp::*__f)() const)
    { return const_mem_fun_ref_t<_Ret, _Tp>(__f); }

  template<typename _Ret, typename _Tp, typename _Arg>
    inline mem_fun1_t<_Ret, _Tp, _Arg>
    mem_fun(_Ret (_Tp::*__f)(_Arg)) //获得二元仿函数
    { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); }

  template<typename _Ret, typename _Tp, typename _Arg>
    inline const_mem_fun1_t<_Ret, _Tp, _Arg>
    mem_fun(_Ret (_Tp::*__f)(_Arg) const)
    { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); }

  template<typename _Ret, typename _Tp, typename _Arg>
    inline mem_fun1_ref_t<_Ret, _Tp, _Arg>
    mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) //获得二元仿函数
    { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }

  template<typename _Ret, typename _Tp, typename _Arg>
    inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg>
    mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const)
    { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值