Function Objects

Many STL algorithms allow you to pass a function pointer into the algorithm to help the algorithm perform its task. For example, the binary_search algorithm that we discussed in Section 23.5.6 is overloaded with a version that requires as its fourth parameter a pointer to a function that takes two arguments and returns a bool value. The binary_search algorithm uses this function to compare the search key to an element in the collection. The function returns TRue if the search key and element being compared are equal; otherwise, the function returns false. This enables binary_search to search a collection of elements for which the element type does not provide an overloaded equality == operator.

STL's designers made the algorithms more flexible by allowing any algorithm that can receive a function pointer to receive an object of a class that overloads the parentheses operator with a function named operator(), provided that the overloaded operator meets the requirements of the algorithmin the case of binary_search, it must receive two arguments and return a bool. An object of such a class is known as a function object and can be used syntactically and semantically like a function or function pointerthe overloaded parentheses operator is invoked by using a function object's name followed by parentheses containing the arguments to the function.

Function objects provide several advantages over function pointers. Since function objects are commonly implemented as class templates that are included into each source code file that uses them, the compiler can inline an overloaded operator() to improve performance. Also, since they are objects of classes, function objects can have data members that operator() can use to perform its task.


Predefined Function Objects of the Standard Template Library

Many predefined function objects can be found in the header . Figure 23.41 lists several of the STL function objects, which are all implemented as class templates. We used the function object less< T > in the set, multiset and priority_queue examples, to specify the sorting order for elements in a container.

Figure 23.41. Function objects in the Standard Library.

STL function objects

Type

divides< T >

arithmetic

equal_to< T >

relational

greater< T >

relational

greater_equal< T >

relational

less< T >

relational

less_equal< T >

relational

logical_and< T >

logical

logical_not< T >

logical

logical_or< T >

logical

minus< T >

arithmetic

modulus< T >

arithmetic

negate< T >

arithmetic

not_equal_to< T >

relational

plus< T >

arithmetic

multiplies< T >

arithmetic

Using the STL Accumulate Algorithm

Figure 23.42 demonstrates the accumulate numeric algorithm (discussed in Fig. 23.30) to calculate the sum of the squares of the elements in a vector. The fourth argument to accumulate is a binary function object (that is, a function object for which operator() takes two arguments) or a function pointer to a binary function (that is, a function that takes two arguments). Function accumulate is demonstrated twiceonce with a function pointer and once with a function object.

Figure 23.42. Binary function object.

(This item is displayed on pages 1188 - 1189 in the print version)

 1 // Fig. 23.42: Fig23_42.cpp
 2 // Demonstrating function objects.
 3 #include 
 4 using std::cout;
 5 using std::endl;
 6
 7 #include  // vector class-template definition
 8 #include  // copy algorithm
 9 #include  // accumulate algorithm
10 #include  // binary_function definition
11 #include  // ostream_iterator
12
13 // binary function adds square of its second argument and the
14 // running total in its first argument, then returns the sum 
15 int sumSquares( int total, int value ) 
16 { 
17  return total + value * value; 
18 } // end function sumSquares 
19
20 // binary function class template defines overloaded operator()
21 // that adds the square of its second argument and running 
22 // total in its first argument, then returns sum 
23 template< typename T > 
24 class SumSquaresClass : public std::binary_function< T, T, T > 
25 { 
26 public: 
27  // add square of value to total and return result 
28  T operator()( const T &total, const T &value ) 
29  { 
30  return total + value * value; 
31  } // end function operator() 
32 }; // end class SumSquaresClass 
33
34 int main()
35 {
36 const int SIZE = 10;
37 int array[ SIZE ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
38 std::vector< int > integers( array, array + SIZE ); // copy of array
39 std::ostream_iterator< int > output( cout, " " );
40 int result;
41
42 cout << "vector integers contains:
";
43 std::copy( integers.begin(), integers.end(), output );
44
45 // calculate sum of squares of elements of vector integers 
46 // using binary function sumSquares 
47 result = std::accumulate( integers.begin(), integers.end(),
48  0, sumSquares ); 
49
50 cout << "

Sum of squares of elements in integers using "
51 << "binary
function sumSquares: " << result;
52
53 // calculate sum of squares of elements of vector integers 
54 // using binary function object 
55 result = std::accumulate( integers.begin(), integers.end(),
56  0, SumSquaresClass< int >() ); 
57
58 cout << "

Sum of squares of elements in integers using "
59 << "binary
function object of type "
60 << "SumSquaresClass< int >: " << result << endl;
61 return 0;
62 } // end main
 
 vector integers contains:
 1 2 3 4 5 6 7 8 9 10

 Sum of squares of elements in integers using binary
 function sumSquares: 385

 Sum of squares of elements in integers using binary
 function object of type SumSquaresClass< int >: 385
 

Lines 1518 define a function sumSquares that squares its second argument value, adds that square and its first argument total and returns the sum. Function accumulate will pass each of the elements of the sequence over which it iterates as the second argument to sumSquares in the example. On the first call to sumSquares, the first argument will be the initial value of the total (which is supplied as the third argument to accumulate; 0 in this program). All subsequent calls to sumSquares receive as the first argument the running sum returned by the previous call to sumSquares. When accumulate completes, it returns the sum of the squares of all the elements in the sequence.

Lines 2332 define a class SumSquaresClass that inherits from the class template binary_function (in header file )an empty base class for creating function objects in which operator receives two parameters and returns a value. Class binary_function accepts three type parameters that represent the types of the first argument, second argument and return value of operator, respectively. In this example, the type of these parameters is T (line 24). On the first call to the function object, the first argument will be the initial value of the total (which is supplied as the third argument to accumulate: 0 in this program) and the second argument will be the first element in vector integers. All subsequent calls to operator receive as the first argument the result returned by the previous call to the function object, and the second argument will be the next element in the vector. When accumulate completes, it returns the sum of the squares of all the elements in the vector.

Lines 4748 call function accumulate with a pointer to function sumSquares as its last argument.

The statement at lines 5556 calls function accumulate with an object of class SumSquaresClass as the last argument. The expression SumSquaresClass< int >() creates an instance of class SumSquaresClass (a function object) that is passed to accumulate, which sends the object the message (invokes the function) operator. The statement could be written as two separate statements, as follows:

SumSquaresClass< int > sumSquaresObject;
result = std::accumulate( integers.begin(), integers.end(),
 0, sumSquaresObject );

The first line defines an object of class SumSquaresClass. That object is then passed to function accumulate.






C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627
Simiral book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net