STL之函数对象(function object)

目录

  • 1、概论
  • 2、可适配(adaptable)的关键
  • 3、算术类函数对象
    • 3.1、示例
  • 4、关系类函数对象
    • 4.1、示例
  • 5、逻辑函数对象
    • 5.1、示例
  • 6、其他


1、概论

如果类定义了调用运算符(即圆括号),则该类的对象称作函数对象(function object)。因为可以调用这种对象,所以我们说这些对象的"行为像函数一样"。

函数对象常常作为泛型算法的实参,并代替函数指针使用。以sort()为例,sort(begin,end)接受两个迭代器作为其参数,默认利用元素类型的<运算符来实现排序。sort(begin,end,comp)则以用户定义的comp函数作为元素比较的根据。通常情况下,可以设计自己的比较函数comp,然后以函数指针当做算法的一个参数。但是函数指针不能满足STL对抽象性的要求,同时函数指针无法和STL其他组件搭配,产生更灵活的变化,因此需要使用函数对象。

STL的函数对象,根据操作数的个数划分,可分为一元和二元函数对象。根据功能划分,可分为算术运算、关系运算、逻辑运算三大类,每个类分别定义了一个执行命名操作的调用运算符。

STL之函数对象(function object)_第1张图片

2、可适配(adaptable)的关键

STL的函数对象可以使算法更灵活,而更加灵活的关键,在于STL的函数对象的可适配性(adaptability)。STL的函数对象应该有能力被函数适配器修饰,彼此像积木一样地串接。为了拥有适配能力,每一个函数对象必须定义自己的相应类型,就像迭代器如果要融入STL,也必须依照规定定义自己的5个相应类型一样,这些相应类型是为了让适配器能够取出,获得函数对象的某些信息。

函数对象的相应类型主要用来表现函数参数类型和返回值类型。标准库在中定义了两个类,分别代表一元函数对象和二元函数对象,其中没有任何数据成员或成员函数,只有一些类型定义。

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;

  /// @c second_argument_type is the type of the second argument
  typedef _Arg2 second_argument_type;

  /// @c result_type is the return type
  typedef _Result result_type;
};

3、算术类函数对象

算术类函数对象包括:plus、minus、multiplies、divides、modulus、negate

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

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

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

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

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

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

3.1、示例

#include 
#include 
using namespace std;

int main()
{
    plus<int> intplus;
    minus<int> intminus;
    multiplies<int> intmultiplies;
    divides<int> intdivides;
    modulus<int> intmodulus;
    negate<int> intnegate;

    cout<<intplus(1,2)<<endl;  //3
    cout<<intminus(1,2)<<endl;  //-1
    cout<<intmultiplies(1,2)<<endl;  //2
    cout<<intdivides(1,2)<<endl;  //0
    cout<<intmodulus(1,2)<<endl;  //1
    cout<<intnegate(1)<<endl;  //-1
    return 0;
}

4、关系类函数对象

关系类函数对象包括:equal_to、not_equal_to、greater、greater_equal、less、less_equal

template <typename _Tp>
struct equal_to : public binary_function<_Tp, _Tp, bool>
{
  _GLIBCXX14_CONSTEXPR
  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>
{
  _GLIBCXX14_CONSTEXPR
  bool
  operator()(const _Tp &__x, const _Tp &__y) const
  {
    return __x != __y;
  }
};

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

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

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

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

4.1、示例

#include 
#include 
using namespace std;

int main()
{
    equal_to<int> intequal_to;
    not_equal_to<int> intnotequal_to;
    greater<int> intgreater;
    greater_equal<int> intgreater_equal;
    less<int> intless;
    less_equal<int> intless_equal;

    cout<<intequal_to(1,2)<<endl;  //0
    cout<<intnotequal_to(1,2)<<endl;  //1
    cout<<intgreater(1,2)<<endl;  //0
    cout<<intgreater_equal(1,2)<<endl;  //0
    cout<<intless(1,2)<<endl;  //1
    cout<<intless_equal(1,2)<<endl;  //1
    return 0;
}

5、逻辑函数对象

逻辑函数对象包括:logical_and、logical_or、logical_not

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

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

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

5.1、示例

#include 
#include 
using namespace std;

int main()
{
    logical_and<int> int_and;
    logical_or<int> int_or;
    logical_not<int> int_not;

    cout<<int_and(1,0)<<endl;  //0
    cout<<int_or(1,0)<<endl;  //1
    cout<<int_not(1)<<endl;  //0

    return 0;
}

6、其他

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

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

// Partial specialization, avoids confusing errors in e.g. std::set.
template <typename _Tp>
struct _Identity<const _Tp> : _Identity<_Tp>
{
};

template <typename _Pair>
struct _Select1st
    : 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;
  }

#if __cplusplus >= 201103L
  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;
  }
#endif
};

template <typename _Pair>
struct _Select2nd
    : 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;
  }
};

你可能感兴趣的:(STL源码剖析)