STL源码剖析—仿函数(函数对象)

第七章 仿函数(函数对象)

7.1 仿函数概观

  • 什么是仿函数(函数对象)?

    就实现观点而言,仿函数实际上是一个“行为类似函数”的对象,为了能够“行为类似函数”,其类别定义中必须自定义(重载、重写)operator()运算符。

    简单点说,仿函数就是一个对象,只不过是重载了operator()运算符,并且可以保存状态。

  • 为什么要使用仿函数而不使用函数指针呢?
    原因在于函数指针不能满足STL对抽象性的要求,也不能和配接器adapter搭配,产生更加灵活的变化。

  • 运用系统的仿函数必须包括头文件:

  • STL仿函数的分类:

    • 操作数分类:
      • 一元仿函数
      • 二元仿函数
    • 功能分类
      • 算术运算
      • 关系运算
      • 逻辑运算

7.2 可配接的关键

为了能够拥有配接能力,每一个仿函数必须定义自己的响应型别。这些型别是为了让配接器能够取出,获得仿函数的某些信息。

  • 任何仿函数,若想要拥有与配接器配接的能力,就必须继承其中的任意一个class
  • 中定义的两个仿函数:
    • unary_function
      //一元仿函数
      template 
      struct unary_function{
        typedef Arg argument_type;
        typedef Result result_type;
      }
      
    • binary_function
      //二元仿函数
      template 
      struct binary_function{
        typedef Arg1 firs_argument_type;
        typedef Arg2 second_argument_type;
        typedef Result result_type;
      }
      

7.4 算术类仿函数

  • STL内建的“算术类仿函数”
    • STL内建

      • 加法:plus
      • 减法:minus
      • 乘法:multiplies
      • 除法:divides
      • 模取:modulus
      • 否定:negate
    • 加法:plus

      template 
      struct plus:public binary_function{
        T operator()(const T & x,const T & y) const {return x + y;}
      };
      
    • 减法:minus

      template 
      struct minus:public binary_function{
        T operator()(const T & x,const T & y) const {return x - y;}
      };
      
    • 乘法:multiplies

      tmeplate
      struct muliplies:public binary_function{
        T operator()(const T & x,const T & y) const {return x * y;}
      };
      
    • 除法:divides

      tmeplate
      struct divides:public binary_function{
        T operator()(const T & x,const T & y) const {return x / y;}
      };
      
    • 模取:modulus

      tmeplate
      struct modulus:public binary_function{
        T operator()(const T & x,const T & y) const {return x % y;}
      };
      
    • 否定:negate

      tmeplate
      struct negate:public unary_function{
        T operator()(const T & x) const {return -x;}
      };
      
    • 证同元素

      所谓“运算op的证同元素”,意思是数值A若与该元素做op运算,会得到A自己。例如加法的证同元素是0,任何元素加上0都是自己本身。乘法的证同元素是1,任何元素乘1都为元素本身。

      • 这些函数并非STL规格的一员,但许多STL实现都有他们。
        template
        inline
        T identity_element(plus)
        {return T(0);}
        
        template
        inline
        T identity_element(multiplies)
        {return T(1);}
        

7.4 关系运算类仿函数

  • STL内建的“关系运算仿函数”
    • STL内建的所有
      • 等于:equal_to
      • 不等于:not_equal_to
      • 大于:greater
      • 大于或等于:greater_equal
      • 小于:less
      • 小于或等于:less_equal
    • 等于:equal_to
    template
    struct equal_to:public binary_function{
      bool operator()(const T & x,const T & y) const {return x == y;}
    }
    
    • 不等于:not_equal_to
    template
    struct not_equal_to:public binary_function{
      bool operator()(const T & x,const T & y) const {return x != y;}
    }
    
    • 大于:greater
    template
    struct greater:public binary_function{
      bool operator()(const T & x,const T & y) const {return x > y;}
    }
    
    • 大于或等于:greater_equal
    template
    struct greater_equal:public binary_function{
      bool operator()(const T & x,const T & y) const {return x >= y;}
    }
    
    • 小于:less
    template
    struct less:public binary_function{
      bool operator()(const T & x,const T & y) const {return x < y;}
    }
    
    • 小于或等于:less_equal
    template
    struct less_equal:public binary_function{
      bool operator()(const T & x,const T & y) const {return x <= y;}
    }
    

逻辑运算符仿函数

  • STL内建的“逻辑运算符仿函数”支持And,Or,Not三种。
    • STL内建
      • 逻辑运算And:logical_and
      • 逻辑运算Or:logical_or
      • 逻辑运算Not:logical_not
    • 逻辑运算And:logical_and
      template
      struct logical_and:public binary_function{
        bool operator()(const T & x,const T & y) const {return x&&y;}
      }
      
    • 逻辑运算Or:logical_or
      template
      struct logical_or:public binary_function{
        bool operator()(const T & x,const T & y) const {return x||y;}
      }
      
    • 逻辑运算Not:logical_not
      template
      struct logical_not:public unary_function{
        bool operator()(const T & x) const {return !x;}
      }
      

证同(identity)、选择(select)、投射(project)

//证同函数。任何数值通过此函数后,不会有任何改变
//此式运用于,用来指定RB-tree所需的KeyOfValue op
//set元素键值即实值,所以采用identity
template 
struct identity : public unary_function{
  const T& operator()const T& x) const { return x; }
}

//选择函数:接收一个pair,返回其第一元素
//此式运用于,用来指定RB-tree所需的KeyOfValue op
//由于map系以pair元素的第一元素为其键值,所以采用select1st
template 
struct select1st : public unary_function
{
  const typename Pair::first::first_type& operator()(const Pair& x)const{
    return x.first;
  }
}

//选择函数:接收一个Pair,传回其第二元素
//SGI STL未运用此式
template 
struct select2nd : public unary_function
{
  const typename Pair::first::second_type& operator()(const Pair& x)const{
    return x.second;
  }
}

//投射函数:传回第一参数,忽略第二参数
//SGI STL未运用此式
template
struct project1st : public binary_function{
  Arg1 operator()(const Arg1& x,const Arg2&)const{ return x; }
}

//投射函数:传回第二参数,忽略第一参数
//SGI STL未运用此式
template
struct project2nd : public binary_function{
  Arg1 operator()(const Arg1&,const Arg2& y)const{ return y; }
}

你可能感兴趣的:(C/C++)