bool operator()(const T & v) { return tooBig
};
That is, you can use the following:
TooBig2
int x;
cin >> x;
if (tB100(x)) // same as if (tooBig(x,100))
...
So the call tB100(x) is the same as tooBig(x,100), but the two-argument function is converted to a one-argument function object, with the second argument being used to construct the function object. In short, the class functor TooBig2 is a function adapter that adapts a function to meet a different interface.
As noted in the listing, C++11’s initializer-list feature simplifies initialization. You can replace
int vals[10] = {50, 100, 90, 180, 60, 210, 415, 88, 188, 201};
list
list
with this:
list
list
Predefined Functors
The STL defines several elementary functors. They perform actions such as adding two values and comparing two values for equality. They are provided to help support STL functions that take functions as arguments. For example, consider the transform() function. It has two versions. The first version takes four arguments. The first two arguments are iterators that specify a range in a container. (By now you must be familiar with that approach.) The third is an iterator that specifies where to copy the result. The final is a functor that is applied to each element in the range to produce each new element in the result. For example, consider the following:
const int LIM = 5;
double arr1[LIM] = {36, 39, 42, 45, 48};
vector
ostream_iterator
transform(gr8.begin(), gr8.end(), out, sqrt);
This code calculates the square root of each element and sends the resulting values to the output stream. The destination iterator can be in the original range. For example, replacing out in this example with gr8.begin() would copy the new values over the old values. Clearly, the functor used must be one that works with a single argument.
The second version uses a function that takes two arguments, applying the function to one element from each of two ranges. It takes an additional argument, which comes third in order, identifying the start of the second range. For example, if m8 were a second vector
transform(gr8.begin(), gr8.end(), m8.begin(), out, mean);
Now suppose you want to add the two arrays. You can’t use + as an argument because, for type double, + is a built-in operator, not a function. You could define a function to add two numbers and use it:
double add(double x, double y) { return x + y; }
...
transform(gr8.begin(), gr8.end(), m8.begin(), out, add);
But then you’d have to define a separate function for each type. It would be better to define a template, except that you don’t have to because the STL already has. The functional (formerly function.h) header defines several template class function objects, including one called plus<>().
Using the plus<> class for ordinary addition is possible, if awkward:
#include
...
plus
double y = add(2.2, 3.4); // using plus
But it makes it easy to provide a function object as an argument:
transform(gr8.begin(), gr8.end(), m8.begin(), out, plus
Here, rather than create a named object, the code uses the plus
The STL provides functor equivalents for all the built-in arithmetic, relational, and logical operators. Table 16.12 shows the names for these functor equivalents. They can be used with the C++ built-in types or with any user-defined type that overloads the corresponding operator.
Table 16.12. Operators and Functor Equivalents
Caution
Older C++ implementations use the functor name times instead of multiplies.
Adaptable Functors and Function Adapters