Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using STL algorithms, is it better to pass a function pointer or a functor?

Tags:

c++

functor

stl

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!

like image 638
Gab Royer Avatar asked Jun 22 '09 14:06

Gab Royer


People also ask

What is the difference between a functor and a function pointer Why might we want to use a functor instead of a function pointer?

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.

What is the benefit of functor?

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.

Why do we use functor in C++?

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.

Are functors part of STL?

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.


2 Answers

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::bindx 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.

like image 124
Konrad Rudolph Avatar answered Sep 17 '22 21:09

Konrad Rudolph


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].

like image 22
MSN Avatar answered Sep 18 '22 21:09

MSN