function objects stl:
Function objects are another example of the power of generic programming and the concept of pure abstraction. You could say that anything that behaves like a function is a function. So, if you define an object that behaves as a function, it can be used as a function.
So, what is the behavior of a function? The answer is: A functional behavior is something that you can call by using parentheses and passing arguments. For example:
function (arg1 ,arg2); //a function call
So, if you want objects to behave this way you have to make it possible to "call" them by using parentheses and passing arguments. Yes, that's possible (there are rarely things that are not possible in C++). All you have to do is define operator () with the appropriate parameter types:
class X {
public:
//define "function call" operator
return-value operator() (arguments) const;
...
};
public:
//define "function call" operator
return-value operator() (arguments) const;
...
};
Now you can use objects of this class to behave as a function that you can call:
X fo;
...
fo(arg1, arg2); //call operator () for function object fo
...
fo(arg1, arg2); //call operator () for function object fo
The call is equivalent to:
fo.operator() (arg1,arg2); //call operator () for function object fo
The following is a complete example. This is the function object version of a previous example that did the same with an ordinary function:
Example:
The class PrintInt defines objects for which you can call operator () with an int argument. The expression
PrintInt()
in the statement
for_each (coll.begin(), coll.end(),
PrintInt());
PrintInt());
creates a temporary object of this class, which is passed to the for_each() algorithm as an argument. The for_each() algorithm is written like this:
namespace std {
template <class Iterator, class Operation>
Operation for_each (Iterator act, Iterator end, Operation op)
{
while (act != end) { //as long as not reached the end
op (*act); // - call op() for actual element
act++; // - move iterator to the next element
}
return op; }
}
}
template <class Iterator, class Operation>
Operation for_each (Iterator act, Iterator end, Operation op)
{
while (act != end) { //as long as not reached the end
op (*act); // - call op() for actual element
act++; // - move iterator to the next element
}
return op; }
}
}
for_each() uses the temporary function object op to call op(*act) for each element act. If the third parameter is an ordinary function, it simply calls it with *act as an argument. If the third parameter is a function object, it calls operator () for the function object op with *act as an argument. Thus, in this example program for_each() calls:
PrintInt::operator()(*act)
You may be wondering what all this is good for. You might even think that function objects look strange, nasty, or nonsensical. It is true that they do complicate code. However, function objects are more than functions, and they have some advantages:
See Also:
No comments:
Post a Comment