Function Object in C++
Function object is very userful to use member function or non-member function as callback mechanism,
Same as event or delegate in C#.
For pointer to object
1 template <class Return, class Type, class Argument> 2 class MemFunctionObject : public binary_function <Type*,Argument,Return> 3 { 4 Return (Type::*pMemFunction)(Argument); 5 public: 6 explicit MemFunctionObject( Return (Type::*pMF)(Argument) ) : pMemFunction (pMF) 7 { 8 } 9 Return operator() (Type* pObject, A x) const 10 { 11 return (pObject->*pMemFunction)(x); 12 } 13 };
For reference to object
1 template <class Result, class Type, class Argument> 2 class MemFunctionObjectRef: public binary_function <Type,Argument,S> 3 { 4 private: 5 Result (Type::*pMemMethod)(Argument); 6 public: 7 explicit MemFunctionObjectRef ( Result (Type::*p)(Argument) ) : pMemMethod (p) {} 8 Result operator() (Type& refObject, Argument x) const 9 { 10 return (refObject.*pMemMethod)(x); 11 } 12 };
binary_function define type's alias
1 template <class Arg1, class Arg2, class Result> 2 struct binary_function { 3 typedef Arg1 first_argument_type; 4 typedef Arg2 second_argument_type; 5 typedef Result result_type; 6 };
Now, wo can define a function to generate a function object
1 template <class Result, class Type, class Argument> 2 MemFunctionObject<Result,Type,Argument> MemFunction(Result (Type::*f)(Argument)) 3 { 4 return MemFunctionObject<Result,Type,Argument>(f); 5 }
How to use:
1 // mem_fun example 2 #include <iostream> 3 #include <functional> 4 #include <vector> 5 #include <algorithm> 6 #include <string> 7 using namespace std; 8 9 int main () { 10 vector <string*> numbers; 11 12 // populate vector of pointers: 13 numbers.push_back ( new string ("one") ); 14 numbers.push_back ( new string ("two") ); 15 numbers.push_back ( new string ("three") ); 16 numbers.push_back ( new string ("four") ); 17 numbers.push_back ( new string ("five") ); 18 19 vector <int> lengths ( numbers.size() ); 20 21 transform (numbers.begin(), numbers.end(), lengths.begin(),MemFunction(&string::append,_1,"_test!").length()); 22 23 for (int i=0; i<5; i++) { 24 cout << *numbers[i] << " has " << lengths[i] << " letters.\n"; 25 } 26 return 0; 27 }