STL 函数适配器(function adapter)

函数适配器(function adapter):通过不同函数适配器的绑定,组合和修饰能力,可以实现强大的功能,配合STL泛型算法完成复杂功能。

绑定(bind)

template <class _Operation> 
class binder1st
  : public unary_function<typename _Operation::second_argument_type,
                          typename _Operation::result_type> {
protected:
  _Operation op;
  typename _Operation::first_argument_type value;
public:
  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); 
  }
};

template <class _Operation, class _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));
}

bind1st函数有两个参数,被绑定参数的仿函数__fn,以及待绑定到仿函数上的参数值__x。在函数中构建并返回了binder1st对象,并设置了相应的构造参数。

binder1st类中有一个仿函数(函数对象)成员op和待绑定参数value,binder1st构造函数会用传入的仿函数类和待绑定参数来初始化其类成员op与value。

binder1st本身也是一个仿函数类(functor),在类中定义的函数调用操作符(operator())内完成了仿函数的实际功能。该函数有一个参数__x,指定操作的第二参数。然后用调用待绑定参数类op的构造函数,并用value和__x进行初始化。返回的对象的第一个参数就被绑定到binder1st的待绑定参数成员value,以实现参数绑定的功能。

binder1st的原理与binder1st相类似。

否定(not)

template <class _Predicate>
inline unary_negate<_Predicate> 
not1(const _Predicate& __pred)
{
  return unary_negate<_Predicate>(__pred);
}

template <class _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);
  }
};

not1表示一元谓词否定,传入仿函数对象,返回与传入对象的结果相反的一元谓词仿函数对象。
not2表示二元谓词否定,传入仿函数对象,返回与传入对象的结果相反的二元谓词仿函数对象。

合成(compose)

合成的作用类似于数学中的复合函数,分为一元合成和二元合成:
一元合成:h(x)=f(g(x))
二元合成:h(x)=f(g1(x),g2(x))

template <class _Operation1, class _Operation2>
inline unary_compose<_Operation1,_Operation2> 
compose1(const _Operation1& __fn1, const _Operation2& __fn2)
{
  return unary_compose<_Operation1,_Operation2>(__fn1, __fn2);
}

template <class _Operation1, class _Operation2>
class unary_compose
  : public unary_function<typename _Operation2::argument_type,
                          typename _Operation1::result_type> 
{
protected:
  _Operation1 _M_fn1;
  _Operation2 _M_fn2;
public:
  unary_compose(const _Operation1& __x, const _Operation2& __y) 
    : _M_fn1(__x), _M_fn2(__y) {}
  typename _Operation1::result_type
  operator()(const typename _Operation2::argument_type& __x) const {
    return _M_fn1(_M_fn2(__x));        //在此处发挥作用
  }
};

二元合成的原理和一元合成相类型。

  binary_compose(const _Operation1& __x, const _Operation2& __y, 
                 const _Operation3& __z) 
    : _M_fn1(__x), _M_fn2(__y), _M_fn3(__z) { }
  typename _Operation1::result_type
  operator()(const typename _Operation2::argument_type& __x) const {
    return _M_fn1(_M_fn2(__x), _M_fn3(__x));
  }

函数指针(ptr_mem)

这种配接器使我们能够将一般函数当作仿函数使用。
如果不使用这里的函数指针适配器先作一番包装,则一般函数无配接能力,无法和前面介绍的其他配接器接轨。

template <class _Arg, class _Result>
inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg))
{
  return pointer_to_unary_function<_Arg, _Result>(__x);
}

template <class _Arg, class _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); }
};

成员函数指针适配器(mem_fun,mem_fun_ref)

这类适配器可将成员函数作为仿函数来使用。
当容器中存放的是类的指针或者引用类型时,利用泛型算法对容器中元素进行处理时,便可使用成员函数指针适配器动态调用类中定义的虚函数,从而实现多态。

成员函数指针适配器按照参数个数,通过引用还是指针调用,以及是否为静态成员函数,可以分为8种:

函数名称 特征
mem_fun(S (T::*f)()) 无参数;pointer;non-const
mem_fun1(S (T::*f)(A)) 有参数;pointer;non-const
mem_fun(S (T::*f)() const) 无参数;pointer;const
mem_fun1(S (T::*f)(A) const) 有参数;pointer;const
mem_fun_ref(S (T::*f)()) 无参数;reference;non-const
mem_fun1_ref(S (T::*f)(A)) 有参数;reference;non-const
mem_fun_ref(S (T::*f)() const) 无参数;reference;const
mem_fun1_ref(S (T::*f)(A) const) 有参数;reference;const
posted @ 2019-12-01 19:33  技术狂人djc  阅读(388)  评论(0编辑  收藏  举报