I l@ve RuBoard |
![]() ![]() |
4.9 Implementing a Function ObjectIn Section 3.6, we looked at the predefined function objects of the standard library. In this section, we look at how to implement our own function objects. A function object is a class that provides an overloaded instance of the function call operator. When the compiler encounters what appears to be a function call, such as lt( ival ); lt can be the name of a function, a pointer to function, or an object of a class that has provided an instance of the function call operator. If lt is a class object, the compiler internally transforms the statement as follows: lt.operator()( ival ); // internal transformation The function call operator can take any number of parameters: none, one, two, and so on. It is used, for example, to support multidimensional subscripting of a Matrix class because the actual subscript operator is limited to accepting one parameter. Let's implement an overloaded instance of the call operator to test whether a value passed to it is less than some other value. We'll call the class LessThan. Each object must be initialized with a value against which to compare. In addition, we support read and write access of that value. Here's our implementation: class LessThan { public: LessThan( int val ) : _val( val ){} int comp_val() const { return _val; } void comp_val( int nval ){ _val = nval; } bool operator()( int value ) const; private: int _val; }; The implementation of the function call operator looks like this: inline bool LessThan:: operator()( int value ) const { return value < _val; } We can explicitly define a LessThan class object in the same way as any other class object: LessThan lt10( 10 ); We invoke the overloaded call operator function by applying the call operator (()) to the class object. For example, int count_less_than( const vector<int> &vec, int comp ) { LessThan lt( comp ); int count = 0; for ( int ix = 0; ix < vec.size(); ++ix ) if ( lt( vec[ ix ] )) ++count; return count; } More typically, we pass a function object as an argument to a generic algorithm: void print_less_than( const vector<int> &vec, int comp, ostream &os = cout ) { LessThan lt( comp ); vector<int>::const_iterator iter = vec.begin(); vector<int>::const_iterator it_end = vec.end(); os << "elements less than " << lt.comp_val() << endl; while (( iter = find_if( iter, it_end, lt )) != it_end ) { os << *iter << ' '; ++iter; } } Here's a small program to exercise these two functions: int main() { int ia[16] = { 17, 12, 44, 9, 18, 45, 6, 14, 23, 67, 9, 0, 27, 55, 8, 16 }; vector<int> vec( ia, ia+16 ); int comp_val = 20; cout << "Number of elements less than " << comp_val << " are " << count_less_than( vec, comp_val ) << endl; print_less_than( vec, comp_val ); } When compiled and executed, the program generates the following output: Number of elements less than 20 are 10 elements less than 20 17 12 9 18 6 14 9 0 8 16 Appendix B provides additional examples of function object definitions. ![]() |
I l@ve RuBoard |
![]() ![]() |