Question

I see function objects used often together with STL algorithms. Did function objects came about because of these algorithms? When do you use a function object in C++? What is its benefits?

Was it helpful?

Solution

As said jdv, functors are used instead of function pointers, that are harder to optimize and inline for the compiler; moreover, a fundamental advantage of functors is that they can easily preserve a state between calls to them1, so they can work differently depending on the other times they have been called, keep track somehow of the parameters they have used, ...

For example, if you want to sum all the elements in two containers of ints you may do something like this:

struct
{
    int sum;
    void operator()(int element) { sum+=element; }
} functor;
functor.sum=0;
functor = std::for_each(your_first_container.begin(), your_first_container.end(), functor);
functor = std::for_each(your_second_container.begin(), your_second_container.end(), functor);
std::cout<<"The sum of all the elements is: "<<functor.sum<<std::endl;

  1. Actually, as R Samuel Klatchko pointed out below, they can support multiple independent states, one for each functor instance:
    A slightly more precise statement is that functors can support multiple independent states (functions can support a single state via statics/globals which is neither thread-safe nor reentrant).
    Functors enables you to use even more complicated states, for example a shared state (static fields) and a private state (instance fields). However this further flexibility is rarely used.

OTHER TIPS

Function objects (functors) are typically used instead of function pointers. Function pointers have the problem that the compiler typically passes them as raw pointers, which makes it hard for the compiler to inline the code later. And they're easier to give parameters.

Function objects were designed to allow a strong layer of abstraction over STL, and in that regard they are great.

However, I prefer to use boost::bind and bind a function to the STL algorithms instead -- usually (although not in cases where the object has a state) that seems a more elegant solution.

std::for_each( callback.begin(), callback.end(), 
    boost::bind(&Callback::call(),_1) 
);

Also, another upcoming alternative are lambda's in C++0x (example shamelessly stolen from Wikipedia):

std::vector<int> someList;
int total = 0;
std::for_each(someList.begin(), someList.end(), [&total](int x) {
  total += x;
});
std::cout << total;

Notice that due to closures, they do not have the restriction of bind about not having a state.

A function object is a function that is also an object, i.e. it has state. Normal functions generally do not have state. They may emulate having state by accessing global variables, but then the state is shared across all invocations.

The idea of encapsulating a function as an object dates back to Lisp and Smalltalk. The C++ idea of functor was a chapter in Jim Coplien's book Advanced C++ Programming Styles and Idioms in 1991. STL used the idiom and further popularized it.

I can't say why they came about - possibly simply because they could!

When do you use a functor? Consider that a functor is just moving the code you'd normally put in a loop into the operator() of a class, they're not that much different from just calling a function in a while loop... except, by using them you allow the compiler to inline the code and you can also pass a pre-constructed object instead, that you've constructed with some state. That latter point makes them very powerful.

Compare the sort algorithm with the CRTs qsort call. They do the same thing, only do it quite differently.

This article has a great in-depth look at function objects, and how it can make code much more powerful, and cleaner too.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top