仿函数(functor)是一种使用上像函数的类,其本质是一个实现了 operato() 函数的类,这种类就有了类似于函数一样的使用行为,这就是仿函数的类。
仿函数在 C++ STL标准库中被大量使用。
1. 仿函数是一个类,不是一个函数
2. 仿函数的类需要重载 operator() 函数,以此拥有函数的行为
/**
* This is one of the @link functors functor base classes@endlink.
*/
template
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;
};
作为拥有一个输入参数的仿函数常用基类,该类主要回答了两个问题:
1. 该仿函数类的输入参数是什么类型:argument_type
2. 该仿函数类的返回参数是什么类型: result_type
/**
* This is one of the @link functors functor base classes@endlink.
*/
template
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;
};
作为拥有两个输入参数的仿函数常用基类,该类主要回答了两个问题:
1. 该仿函数类的输入参数是什么类型:first_argument_type 与 second_argument_type
2. 该仿函数类的返回参数是什么类型: result_type
/// One of the @link arithmetic_functors math functors@endlink.
template
struct plus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template
struct minus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x - __y; }
};
/// One of the @link arithmetic_functors math functors@endlink.
template
struct multiplies : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; }
};
template
struct divides : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x / __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template
struct equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x == __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template
struct less : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
/// One of the @link comparison_functors comparison functors@endlink.
template
struct greater : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x > __y; }
};
template
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; }
};
template
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; }
};
#include
#include
int main()
{
// 1. plus
std::cout << "------ plus ------" << std::endl;
std::vector vec = {1, 3, 5};
std::plus pl;
int init = 0;
int res1 = std::accumulate(vec.begin(), vec.end(), init, pl);
std::cout << res1 << std::endl;
std::cout << "------ plus ------" << std::endl; // 9
// 2. minus
std::cout << "------ minus ------" << std::endl;
init = 10;
std::minus mis;
int res2 = std::accumulate(vec.begin(), vec.end(), init, mis);
std::cout << res2 << std::endl; // 1
std::cout << "------ minus ------" << std::endl;
// 3. multies
std::cout << "------ multies ------" << std::endl;
init = 1;
std::multiplies multiply;
int res3 = std::accumulate(vec.begin(), vec.end(), init, multiply);
std::cout << res3 << std::endl; // 15
std::cout << "------ multies ------" << std::endl;
// 4. divides
std::cout << "------ divides ------" << std::endl;
init = 90;
std::divides divid;
int res4 = std::accumulate(vec.begin(), vec.end(), init, divid);
std::cout << res4 << std::endl; // 6
std::cout << "------ divides ------" << std::endl;
// 5. equal_to
std::cout << "------ equal_to ------" << std::endl;
std::pair pair1 = std::make_pair(1, "abc");
std::pair pair2 = std::make_pair(2, "abc");
std::equal_to equal;
std::_Select2nd> second_argu;
std::cout << equal(second_argu(pair1), second_argu(pair2)) << std::endl;// 1
std::cout << "------ equal_to ------" << std::endl;
// 6. less
std::cout << "------ less ------" << std::endl;
std::less less;
std::cout << less(3, 6) << std::endl; // 1
std::cout << "------ less ------" << std::endl;
// 7. greater
std::cout << "------ greater ------" << std::endl;
std::greater greater;
std::cout << greater(3, 6) << std::endl; // 0
std::cout << "------ greater ------" << std::endl;
// 8. _Select1st
std::cout << "------ _Select1st ------" << std::endl;
std::pair pair3 = std::make_pair(1, "abc");
std::_Select1st> select1st;
std::cout << select1st(pair3) << std::endl; // 1
std::cout << "------ _Select1st ------" << std::endl;
// 9. _Select2nd
std::cout << "------ _Select2nd ------" << std::endl;
std::pair pair4 = std::make_pair(1, "abc");
std::_Select2nd> select2nd;
std::cout << select2nd(pair3) << std::endl; // abc
std::cout << "------ _Select2nd ------" << std::endl;
return 0;
}
输出: