STL源码剖析(二十二)仿函数

仿函数
即函数对象,指具有函数特质的对象。
STL提供的算法,通常有两个版本,一个表现出最常用的某种运算,另一个则表现出泛化的算法流程,允许指定template参数的操作。
允许用户指定任何操作,将某种操作当做算法的参数,可先将该操作设计为一个函数,再将函数指针作为算法的一个参数,或将该操作设计为访函数,再以该函数产生一个对象,以此对象作为算法的参数。
函数指针可满足将整组操作作为算法的参数,但不满足STL对抽象性的要求,也无法与STL其他组件如adapter搭配,产生更灵活的变化。
仿函数是行为类似函数的对象,其类型定义必须自定义函数调用运算符。

可适配的关键
在STL六大组件中,仿函数体积最小、观念最简单、实现最容易,可让算法更灵活。
STL仿函数为了与函数模板配合,必须定义自己的相应类型,就像迭代器需要定义5个相应类型一样。相应类型都是一些typedef,主要用来表现函数参数类型和返回类型,所有必要操作在编绎器全部完成,对程序执行效率没有影响,不带来额外负担。

若以操作数个数分类,仿函数可分为一元和二元仿函数,若以功能划分,可分为算术运算、关系运算、逻辑运算三大类,若使用STL内建的仿函数,包含头文件<functional>头文件即可。

unary_function与binary_function中定义了类型,分别代表一元和二元仿函数,STL不支持三元仿函数,仿函数依个人需求选择继承其一便自动拥有类型定义,也自动拥有适配能力。
算术类仿函数有加plus<T>、减minus<T>、乘multiplies<T>、除divides<T>、模modulus<T>、负negate<T>,用法与一般函数相同,可以使用临时对象执行函数功能,例plus<int>()(a, b)。
关系运算类仿函数有等于equal_to<T>、不等于not_equal_to<T>、大于greater<T>、大于或等于greater_equal<T>、小于less<T>、小于或等于less_equal<T>。
逻辑运算类仿函数有逻辑与logical_and<T>、逻辑或logical_or<T>、逻辑非logical_not<T>。
证同(identity)、选择(select)、投射(project),内部使用。
仿函数主要用途是为了搭配STL算法使用。

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  template<typename _Arg, typename _Result>
    struct unary_function
    {
      /// @c argument_type is the type of the argument
      typedef _Arg 	argument_type; //参数类型定义

      /// @c result_type is the return type
      typedef _Result 	result_type; //返回类型定义
    };

  template<typename _Arg1, typename _Arg2, typename _Result>
    struct binary_function
    {
      /// @c first_argument_type is the type of the first argument
      typedef _Arg1 	first_argument_type; //参数类型1

      /// @c second_argument_type is the type of the second argument
      typedef _Arg2 	second_argument_type; //参数类型2

      /// @c result_type is the return type
      typedef _Result 	result_type; //返回类型
    };

  template<typename _Tp> //继承binary_function
    struct plus : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x + __y; }
    };

  template<typename _Tp>
    struct minus : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x - __y; }
    };

  template<typename _Tp>
    struct multiplies : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x * __y; }
    };

  template<typename _Tp>
    struct divides : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x / __y; }
    };

  template<typename _Tp>
    struct modulus : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x % __y; }
    };

  template<typename _Tp> //继承unary_function
    struct negate : public unary_function<_Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x) const
      { return -__x; }
    };

  template<typename _Tp>
    struct equal_to : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x == __y; }
    };

  template<typename _Tp>
    struct not_equal_to : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x != __y; }
    };

  template<typename _Tp>
    struct greater : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x > __y; }
    };

  template<typename _Tp>
    struct less : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x < __y; }
    };

  template<typename _Tp>
    struct greater_equal : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x >= __y; }
    };

  template<typename _Tp>
    struct less_equal : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x <= __y; }
    };

  template<typename _Tp>
    struct logical_and : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x && __y; }
    };

  template<typename _Tp>
    struct logical_or : public binary_function<_Tp, _Tp, bool>
    {
      bool
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x || __y; }
    };

  template<typename _Tp>
    struct logical_not : public unary_function<_Tp, bool>
    {
      bool
      operator()(const _Tp& __x) const
      { return !__x; }
    };

  template<typename _Tp>
    struct bit_and : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x & __y; }
    };

  template<typename _Tp>
    struct bit_or : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x | __y; }
    };

  template<typename _Tp>
    struct bit_xor : public binary_function<_Tp, _Tp, _Tp>
    {
      _Tp
      operator()(const _Tp& __x, const _Tp& __y) const
      { return __x ^ __y; }
    };

  template<typename _Tp>
    struct _Identity //运用于set中,用来指定RB-tree所需的KeyOfValue
    : public unary_function<_Tp,_Tp>
    {
      _Tp&
      operator()(_Tp& __x) const
      { return __x; }

      const _Tp&
      operator()(const _Tp& __x) const
      { return __x; }
    };

  template<typename _Pair>
    struct _Select1st //运用于map中,用来指定RB-tree所需的KeyOfValue
    : public unary_function<_Pair, typename _Pair::first_type>
    {
      typename _Pair::first_type&
      operator()(_Pair& __x) const
      { return __x.first; }

      const typename _Pair::first_type&
      operator()(const _Pair& __x) const
      { return __x.first; }

      template<typename _Pair2>
        typename _Pair2::first_type&
        operator()(_Pair2& __x) const
        { return __x.first; }

      template<typename _Pair2>
        const typename _Pair2::first_type&
        operator()(const _Pair2& __x) const
        { return __x.first; }
    };

  template<typename _Pair>
    struct _Select2nd //接受pair,传回第二元素,暂无运用
    : public unary_function<_Pair, typename _Pair::second_type>
    {
      typename _Pair::second_type&
      operator()(_Pair& __x) const
      { return __x.second; }

      const typename _Pair::second_type&
      operator()(const _Pair& __x) const
      { return __x.second; }
    };

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值