Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |
As you study some of the examples earlier in this chapter,
you will probably notice the limited utility of the function gt15( ).
What if you want to use a number other than 15 as a comparison threshold? You
may need a gt20( ) or gt25( ) or others as well. Having
to write a separate function is time consuming, but also unreasonable because you
must know all required values when you write your application code.
The latter limitation means that you can t use runtime
values to govern your
searches, which is unacceptable. Overcoming this difficulty requires a way to
pass information to predicates at runtime. For example, you would need a
greater-than function that you can initialize with an arbitrary comparison
value. Unfortunately, you can t pass that value as a function parameter because
unary predicates, such as our gt15( ), are applied to each value in
a sequence individually and must therefore take only one parameter.
The way out of this dilemma is, as always, to create an
abstraction. Here, we need an abstraction that can act like a function as well
as store state, without disturbing the number of function parameters it accepts
when used. This abstraction is called a function object.
A function object is an instance of a class that overloads operator( ), the function call operator. This operator allows an object to be used with
function call syntax. As with any other object, you can initialize it via its
constructors. Here is a function object that can be used in place of gt15( ):
//: C06:GreaterThanN.cpp
#include <iostream>
using namespace std;
class gt_n {
int value;
public:
gt_n(int val) : value(val) {}
bool operator()(int n) { return n > value; }
};
int main() {
gt_n f(4);
cout << f(3) << endl; // Prints 0 (for
false)
cout << f(5) << endl; // Prints 1 (for
true)
} ///:~
The fixed value to compare against (4) is passed when the
function object f is created. The expression f(3) is then evaluated
by the compiler as the following function call:
which returns the value of the expression 3 > value,
which is false when value is 4, as it is in this example.
Since such comparisons apply to types other than int,
it would make sense to define gt_n( ) as a class template. It turns
out you don t need to do it yourself, though the standard library has already
done it for you. The following descriptions of function objects should not only
make that topic clear, but also give you a better understanding of how the
generic algorithms work.
Thinking in C++ Vol 2 - Practical Programming |
Prev |
Home |
Next |