【STL】仿函数or函数对象

仿函数概况

仿函数(functors)是早期的命名,C++标准规格定案后的新名称是函数对象(function objects)。

仿函数主要作用于STL所提供的各种算法,从【STL】算法可以看出算法多版本多功能,离不开仿函数的支持。

就现在而言,仿函数其实就是一个“行为类似函数”的对象。为了实现这个行为,类别定义中必须自定义(重载)function call 运算子(operator() )。这时候就可以使用下面两种用法:
第一种就是产生一个临时对象,然后指定参数,类似下面这种:

greater<int>()(6,4);

第二种不常见,但是一种主流用法:
在这里插入图片描述

可配接的关键

为了实现算法的泛化,以及整个库的复用性。STL仿函数也应该具备能力被函数配接器修饰。每一个仿函数必须定义自己的相应型别,为了能够让配接器取出,获取仿函数信息。

仿函数的相应型别主要用来表现函数参数型别和传回值型别。为了方便,定义了两个classes,分别代表一元仿函数和二元仿函数,没有任何data members 或 member functions,只有一些型别定义。任何仿函数,只需要根据个人需求继承,即可得到相应型别,同时就具备了配接能力。

unary_function

unary_function用来呈现一元函数的参数型别和回返值型别。STL规定,每一个Adaptable Unary Function都应该继承此类别,其定义十分简单:

template <class _Arg, class _Result>
struct unary_function {
  typedef _Arg argument_type;
  typedef _Result result_type;
};

一旦某个仿函数继承了unary_function,用户便可取得该仿函数的参数型别,并以相同手法取得其返回型别。

template <class _Tp>
struct negate : public unary_function<_Tp,_Tp> 
{
  _Tp operator()(const _Tp& __x) const { return -__x; }
};
template <class _Predicate>
class unary_negate: public unary_function<typename _Predicate::argument_type, bool> {
public:
  bool operator()(const typename _Predicate::argument_type& __x) const {
	...
  }
};

binary_function

binary_function用来呈现二元函数的第一参数型别、第二参数型别,以及回返值型别。STL规定,每一个Adaptable 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;
};  

一旦某个仿函数继承了Binary_function,其用户即可取到该仿函数的各种型别:

template <class _Tp>
struct plus : public binary_function<_Tp,_Tp,_Tp> {
  _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; }
};
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:
  typename _Operation::result_type
  operator()(const typename _Operation::second_argument_type& __x) const {
    ...
  }
};

算术类、关系运算类、逻辑运算类仿函数

类别算法
算术类加法、减法、乘法、除法、模取、否定
关系运算类等于、不等于、大于、大于或等于、小于、小于或等于
逻辑运算类And、Or、Not

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

这些仿函数都只是将其参数原封不动地传回。其中某些仿函数对传回参数有刻意的选择,或是刻意的忽略。

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

template <class _Tp> struct identity : public _Identity<_Tp> {};

// select1st and select2nd are extensions: they are not part of the standard.
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 _Pair> struct select1st : public _Select1st<_Pair> {};
template <class _Pair> struct select2nd : public _Select2nd<_Pair> {};

// project1st and project2nd are extensions: they are not part of the standard
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; }
};

template <class _Arg1, class _Arg2> 
struct project1st : public _Project1st<_Arg1, _Arg2> {};

template <class _Arg1, class _Arg2>
struct project2nd : public _Project2nd<_Arg1, _Arg2> {};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值