仿函数
即函数对象,指具有函数特质的对象。
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