函数对象(仿函数 functor)
简单地说,函数对象就是一个重载了()运算符的类实例,它可以像一个函数一样使用。
#include <iostream> using namespace std; class Add { public: int operator ()(const int &a, const int &b) { return (a + b); } double operator ()(const double &a, const double &b) { return (a + b); } }; void main() { Add plus; cout << plus(45, 54) << endl;//99 cout << plus(44.3, 58.4) << endl;//102.7 }
用模板:
#include <iostream> using namespace std; template <typename T> class Add { public: T operator ()(const T &a, const T &b) { return (a + b); } }; void main() { Add<int> plus1; cout << plus1(45, 54) << endl;//99 Add<double> plus2; cout << plus2(44.3, 58.4) << endl;//102.7 }
标准库中的find_if、count_if、for_each等与之相关:
#include <iostream> #include <algorithm> #include <vector> using namespace std; template <typename T> class ShowT { public: void operator ()(const T &a) { cout << a << '\t'; } }; void show(const int &a) { cout << a << '\t'; } void main() { vector<int> vec = {1, 3, 5, 7, 9, 64, 128, 156, 200, 256}; //for_each(vec.begin(), vec.end(), show); //ok for_each(vec.begin(), vec.end(), ShowT<int>()); //ok cout << endl; }
与普通函数不同,因为类可以有数据成员,所以仿函数可以有状态的:
#include <iostream> #include <algorithm> #include <vector> using namespace std; template <typename T> class AddT { T m_data = 0; public: void operator ()(const T &a) { m_data += a; } T result() const { return m_data; } }; void main() { vector<int> vec = {1, 3, 5, 7, 9, 64, 128, 156, 200, 256}; AddT<int> sum = for_each(vec.begin(), vec.end(), AddT<int>()); //for_each返回第三个参数的【拷贝】(A copy of the function object ) cout << sum.result() << endl; }
//函数功能:对一区间[beg,end)执行_Func.并返回_Func. template<class _InIt, class _Fn1> inline _Fn1 _For_each(_InIt _First, _InIt _Last, _Fn1 _Func) { for (;_First != _Last; ++_First) _Func(*_First); return(_Func); } template<class _InIt, class _Fn1> inline _Fn1 for_each(_InIt _First, //start interval _InIt _Last, //endinterval, [_First,_Last) _Fn1_Func) //function object or function(unary_function) { // perform function for each element _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Func); return(_For_each(_Unchecked(_First), _Unchecked(_Last), _Func)); }
template<class _InIt, class _Pr> inline _InIt _Find_if(_InIt _First, _InIt _Last, _Pr _Pred) { // find first satisfying _Pred for (;_First != _Last; ++_First) if(_Pred(*_First))//bool(*pFun)( T ) break; return(_First); } template<class _InIt, class _Pr> inline _InIt find_if(_InIt _First, _InIt _Last, _Pr _Pred) { // find first satisfying _Pred _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Pred); return(_Rechecked(_First, _Find_if(_Unchecked(_First),_Unchecked(_Last), _Pred))); }
template<class _InIt, class _Pr> inline typename iterator_traits<_InIt>::difference_type _Count_if(_InIt _First, _InIt _Last, _Pr _Pred) { // count elements satisfying _Pred typename iterator_traits<_InIt>::difference_type _Count = 0; for (;_First != _Last; ++_First) if(_Pred(*_First)) ++_Count; return(_Count); } template<class _InIt, class _Pr> inline typename iterator_traits<_InIt>::difference_type count_if(_InIt _First, _InIt _Last, _Pr _Pred) { // count elements satisfying _Pred _DEBUG_RANGE(_First, _Last); _DEBUG_POINTER(_Pred); return(_Count_if(_Unchecked(_First), _Unchecked(_Last), _Pred)); }