Skip to content

Latest commit

 

History

History
254 lines (179 loc) · 5.97 KB

44 仿函数.md

File metadata and controls

254 lines (179 loc) · 5.97 KB

仿函数(函数对象)

前言

本节将分析STL六部分之一的仿函数, 在前面分析容器以及算法的时候都有使用过仿函数, 在算法中我们还自定义过仿函数(函数对象), 就是使用struct或者class重载运算符, 就是行为类似于函数的对象.

  • 根据仿函数的操作数可分为 : 一元和二元仿函数.

  • 根据功能可分为 : 算术运算, 关系运算, 逻辑运算.

仿函数与函数指针

STL采用对象重载操作实现函数行为并没有直接定义函数指针来代替仿函数, 主要有几点原因让STL选择仿函数

  1. 函数指针不能满足STL的抽象性
  2. 函数指针不能与STL的其他组件搭配, 不够灵活
  3. 仿函数具有可配接性, 可以满足traits编程, 也是能在编译期间就能完成, 不会有运行时的开销

仿函数分析

一元仿函数

一元仿函数基类(unary_function)

template <class Arg, class Result>
struct unary_function {
    typedef Arg argument_type;	// 参数类型别名
    typedef Result result_type;	// 返回值类型别名
};

二元仿函数

二元仿函数基类(binary_function)

template <class Arg1, class Arg2, class Result>
struct binary_function {
    typedef Arg1 first_argument_type;	// 参数类型别名
    typedef Arg2 second_argument_type;	// 参数类型别名
    typedef Result result_type;	// 返回值类型别名
}; 

算术运算

每个仿函数都继承了二元仿函数, 仿函数可以通过继承使STL更灵活, 函数指针无法这样灵活的操作

  • 加法

    template <class T>
    struct plus : public binary_function<T, T, T> {
        T operator()(const T& x, const T& y) const { return x + y; }
    };
  • 乘法

    template <class T>
    struct multiplies : public binary_function<T, T, T> {
        T operator()(const T& x, const T& y) const { return x * y; }
    };
  • 除法

    template <class T>
    struct divides : public binary_function<T, T, T> {
        T operator()(const T& x, const T& y) const { return x / y; }
    };
  • 减法

    template <class T>
    struct minus : public binary_function<T, T, T> {
    	T operator()(const T& x, const T& y) const { return x - y; }
    };
  • 取模

    template <class T>
    struct modulus : public binary_function<T, T, T> {
        T operator()(const T& x, const T& y) const { return x % y; }
    };
  • 相反

    // 继承的是一元仿函数
    template <class T>
    struct negate : public unary_function<T, T> {
        T operator()(const T& x) const { return -x; }
    };

正同元素

正同元素 : 数值A与该元素做op得到的依然还是A.

template <class T> inline T identity_element(plus<T>) { return T(0); }
// 在stl_numeric.h的power中有使用
template <class T> inline T identity_element(multiplies<T>) { return T(1); }

关系运算类

  • 等于

    template <class T>
    struct equal_to : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x == y; }
    };
  • 不等于

    template <class T>
    struct not_equal_to : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x != y; }
    };
  • 大于

    template <class T>
    struct greater : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x > y; }
    };
  • 小于

    template <class T>
    struct less : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x < y; }
    };

    ...

逻辑运算类

  • template <class T>
    struct logical_or : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x || y; }
    };
  • template <class T>
    struct logical_and : public binary_function<T, T, bool> {
        bool operator()(const T& x, const T& y) const { return x && y; }
    };
  • template <class T>
    struct logical_not : public unary_function<T, bool> {
        bool operator()(const T& x) const { return !x; }
    };

正同,选择,投射

正同 : 任何数值调用该函数都不会有改变

选择 : 接受一个pair类型, 并且返回第一个元素或者第二个元素

投影 : 接受一个pair类型, 忽略第二个元素返回第一个元素或者忽略第一个元素返回第二个元素

  • 正同

    template <class T>
    struct identity : public unary_function<T, T> {
      const T& operator()(const T& x) const { return x; }
    };
  • 选择

    // 选择第一个元素
    template <class Pair>
    struct select1st : public unary_function<Pair, typename Pair::first_type> {
      const typename Pair::first_type& operator()(const Pair& x) const
      {
        return x.first;
      }
    };
    // 选择第二个元素
    template <class Pair>
    struct select2nd : public unary_function<Pair, typename Pair::second_type> {
      const typename Pair::second_type& operator()(const Pair& x) const
      {
        return x.second;
      }
    };
  • 投影

    // 忽略第二个元素返回第一个元素
    template <class Arg1, class Arg2>
    struct project1st : public binary_function<Arg1, Arg2, Arg1> {
      Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
    };
    // 忽略第一个元素返回第二个元素
    template <class Arg1, class Arg2>
    struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
      Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
    };

总结

仿函数使STL变得非常的灵活, 用户也可以自定义, 并且提供接口关联配接器, 下一节我们就分析STL最后的组件--配接器.