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:
class functor {
public:
void operator()(int i);
};
...
for_each(a.begin(), a.end(), functor());
Edit: Should have formulated it this way, in what situation is one of the above method preferable to the other?
Thanks a lot!
While either a functor or function would work, functors are actually more efficient since calling them does not require any indirection. The compiler can statically determine from the functor type which overloaded operator is called, while calling through a function pointer generally requires a dereference at runtime.
A function pointer allows a pointer to a function to be passed as a parameter to another function. Function Objects (Functors) - C++ allows the function call operator() to be overloaded, such that an object instantiated from a class can be "called" like a function.
A C++ functor (function object) is a class or struct object that can be called like a function. It overloads the function-call operator () and allows us to use an object like a function.
Function objects (also called functors) are an STL feature that you may not employ immediately when you start using the STL. They are, however, very useful in many situations and an STL facility with which you should become acquainted.
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.
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]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With