一 仿函数的概念
1. 定义
仿函数(functor)是一种使用上像函数的类,其本质是一个实现了 operato() 函数的类,这种类就有了类似于函数一样的使用行为,这就是仿函数的类。
仿函数在 C++ STL标准库中被大量使用。
2. 特点
1. 仿函数是一个类,不是一个函数
2. 仿函数的类需要重载 operator() 函数,以此拥有函数的行为
二 STL 中常见的 仿函数介绍
1. 基类
1.1 unary_function
/**
* This is one of the @link functors functor base classes@endlink.
*/
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;
};
作为拥有一个输入参数的仿函数常用基类,该类主要回答了两个问题:
1. 该仿函数类的输入参数是什么类型:argument_type
2. 该仿函数类的返回参数是什么类型: result_type
1.2 binary_function
/**
* This is one of the @link functors functor base classes@endlink.
*/
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;
};
作为拥有两个输入参数的仿函数常用基类,该类主要回答了两个问题:
1. 该仿函数类的输入参数是什么类型:first_argument_type 与 second_argument_type
2. 该仿函数类的返回参数是什么类型: result_type
2. STL 中常见仿函数
2.1 plus
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct plus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x + __y; }
};
2.2 minus
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct minus : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x - __y; }
};
2.3 multiplies
/// One of the @link arithmetic_functors math functors@endlink.
template<typename _Tp>
struct multiplies : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x * __y; }
};
2.4 divides
template<typename _Tp>
struct divides : public binary_function<_Tp, _Tp, _Tp>
{
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x / __y; }
};
2.5 equal_to
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct equal_to : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x == __y; }
};
2.6 less
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct less : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x < __y; }
};
2.7 greater
/// One of the @link comparison_functors comparison functors@endlink.
template<typename _Tp>
struct greater : public binary_function<_Tp, _Tp, bool>
{
bool
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x > __y; }
};
2.8 _Select1st
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; }
};
2.9 _Select2nd
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; }
};
3. 使用例子
#include<algorithm>
#include<iostream>
int main()
{
// 1. plus
std::cout << "------ plus ------" << std::endl;
std::vector<int> vec = {1, 3, 5};
std::plus<int> 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<int> 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<int> 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<int> 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<int, std::string> pair1 = std::make_pair(1, "abc");
std::pair<int, std::string> pair2 = std::make_pair(2, "abc");
std::equal_to<std::string> equal;
std::_Select2nd<std::pair<int, std::string>> 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<int> less;
std::cout << less(3, 6) << std::endl; // 1
std::cout << "------ less ------" << std::endl;
// 7. greater
std::cout << "------ greater ------" << std::endl;
std::greater<int> greater;
std::cout << greater(3, 6) << std::endl; // 0
std::cout << "------ greater ------" << std::endl;
// 8. _Select1st
std::cout << "------ _Select1st ------" << std::endl;
std::pair<int, std::string> pair3 = std::make_pair(1, "abc");
std::_Select1st<std::pair<int, std::string>> select1st;
std::cout << select1st(pair3) << std::endl; // 1
std::cout << "------ _Select1st ------" << std::endl;
// 9. _Select2nd
std::cout << "------ _Select2nd ------" << std::endl;
std::pair<int, std::string> pair4 = std::make_pair(1, "abc");
std::_Select2nd<std::pair<int, std::string>> select2nd;
std::cout << select2nd(pair3) << std::endl; // abc
std::cout << "------ _Select2nd ------" << std::endl;
return 0;
}
输出: