Both C and C++ support function pointers, which provide a way to pass around instructions on how to perform an operation. But function pointers are limited because functions must be fully specified at compile time. What do I mean? Let's say that you're writing a mail program to view an inbox, and you'd like to give the user the ability to sort the inbox on different fields--to, from, date, etc. You might try using a sort routine that takes a function pointer capable of comparing the messages, but there's one problem--there are a lot of different ways you might want to compare messages. You could create different functions that differ only by the field of the message on which the comparison occurs, but that limits you to sorting on the fields that have been hard-coded into the program. It's also going to lead to a lot of if-then-else blocks that differ only by the function passed into the sort routine.




What you'd really like is the ability to pass in a third argument to your comparison function, telling it which field to look at. But to make this work, you'd have to write your own sort routine that knows about the third argument; you can't use a generic routine like the STL's sort function because you can't tell it to pass in a third argument to the comparator. Instead, you somehow need the ability to "embed" what field to sort on inside the function.

It turns out that you can get this behavior in C++ (but not in C) through the use of function objects (aka "functors"). Functors are objects that can be treated as though they are a function or function pointer--you could write code that looks like this:

myFunctorClass functor;
functor( 1, 2, 3 );
This code works because C++ allows you to overload operator(), the "function call" operator. The function call operator can take any number of arguments of any types and return anything it wishes to. (It's probably the most flexible operator that can be overloaded; all the other operators have a fixed number of arguments.) For ease of discussion, when an object's operator() is invoked, I'll refer to it as "calling" the object as though it were a function being called.

While overloading operator() is nice, the really cool thing about functors is that their lifecycle is more flexible than that of a function--you can use a a functor's constructor to embed information that is later used inside the implementation of operator().

Let's look at an example. This example creates a functor class with a constructor that takes an integer argument and saves it. When objects of the class are "called", it will return the result of adding the saved value and the argument to the functor:

#include <iostream>

class myFunctorClass
{
    public:
        myFunctorClass (int x) : _x( x ) {}
        int operator() (int y) { return _x + y; }
    private:
        int _x;
};

int main()
{
    myFunctorClass addFive( 5 );
    std::cout << addFive( 6 );

    return 0;
}
In short, the act of constructing an object lets you give the functor information that it can use inside the implementation of its function-like behavior (when the functor is called through operator()).

Posted By :-Cplusplusprogramming
Designed By Blogger Templates | Templatelib & Distributed By Blogspot Templates