Which of these 2 methods is better and why?
Method 1:
void fun(int i) {
//do stuff
}
...
for_each(a.begin(), a.end(), fun);
Method 2
A functor can be more easily inlined, so it may be a factor to consider when performance is important.
#1 is simpler to declare the function
while #2 the functor looks more like a function call.
(Sometime you have to despair of c++ syntax)
One big advantage of a function object over a function pointer is that you can more easily bind up some arguments at function object construction.
An example of a functor that might do this would be
class multiplyBy
{
private:
int m_whatToMultiplyBy;
public:
multiplyBy(int whatToMultiplyBy) :
m_whatToMultiplyBy(whatToMultiplyBy)
{
}
void operator()(int& i)
{
i = m_whatToMultiplyBy * i;
}
}
...
// double the array
for_each(a.begin(), a.end(), multiplyBy(2));
This "binding" of arguments can be done quite nicely with boost::bind and boost::function if boost is available to you.
To clear up a misconception of what a compiler can inline, a good enough compiler can inline function pointers. It can just inline function objects more easily since there is more static information available. E.g., a pointer to a function that takes no parameters and returns a bool is of type bool (*)(), while a functor has an explicit type, namely, the functor, and the template instantiation can statically call the functor operator, rather than having to call through a function pointer.
In practice, though, it's mainly a matter of giving the compiler enough information to optimize effectively.
For example, Visual C++ 2008, given the following code with full optimizations:
#include "stdafx.h"
#include <algorithm>
const char print_me[]= "hello!";
class print_functor
{
public:
void operator()(char c)
{
printf("%c", c);
}
};
void print_function(char c)
{
printf("%c", c);
}
int _tmain(int argc, _TCHAR* argv[])
{
std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_functor());
printf("\n");
std::for_each(print_me, print_me + sizeof(print_me)/sizeof(print_me[0]), print_function);
return 0;
}
inlines both std::for_each
calls completely. Incidentally, on the PC, the first for_each has an unnecessary lea ecx, [ecx]
.
Functors may (and will) be trivially inlined – this isn't done for regular function pointers.
Thus, functors have a real performance benefit which may be huge in tight loops. Furthermore, functors are generally more easily composable and in particuler play nicer with the STL: std::bind
x
doesn't work on function pointers, for instance.
I hate how they clutter the code but given all the advantages, I'd prefer them over function pointers any time.
My opinion - #1 is better, because it's simpler.
Just because something can be an object, doesn't mean it should be one. I'm sure there are cases where the functor makes sense, but in most cases there's probably no need for it.