Why Functors?

I was looking around stackoverflow when I came across the term ‘Functor’. Digging in further, and after an hour of googling – I’ve come to the conclusion that it’s a “more flexible” way of functions.

We’ll start off with a definition – taken from here

What are Functors ?

Functors are functions with a state. In C++ you can realize them as a class with one or more private members to store the state and with an overloaded operator () to execute the function.

Right – time for a small example

struct Add {
  int operator()(int a, int b) {
      return a+b;
  }
};

Simply put, the struct Add overloads the () operator, and returns the sum of two input parameters. This can be called as follows

 
Add inst;
std::cout << inst(4,5);

That was easy – but then why do all that nonsense, when we can simply define a function to add two numbers?!

The answer lies in the fact that, functors can hold state. This can be illustrated by the following example to find average of numbers using stdlib.

struct Avg {
  std::size_t num; 
  double sum;
  Avg() : num(0), sum(0) { }
  void operator()(int a) {
      sum+=(double)a;
      ++num;
  }
  double operator()() {
    return sum/(double)num;
  }
  
};

int main() {
  Avg inst;
  std::vector<int> x = {1,2,3,4,5,6,7,8,9,10,11};
  inst = std::for_each(x.begin(), x.end(), Avg());
  std::cout << inst();
  return 0;
}

Obviously, you need variable sum and num to keep track of number of variables ( if its not known earlier ). So by using a functor, we keep state – storing values of sum and num. The stdlib algorithm for_each iterates through the vector and returns the functor.

Boost provides a boost::function – which can be used to create functors from normal functions – or wrap functors around.

void display(int x) {
  std::cout << "Call function with" << x;
}

int main() {
  boost::function<void (int)> fctr = &display; 
  return 0;
}

or use boost::bind to bind to boost::function as follows


#include <boost/function.hpp>
#include <boost/bind.hpp>

void display(int x) {
  std::cout << "Call function with" << x;
}

int main() {
  boost::function<void ()> fctr = boost::bind(&display, 1);
  
  return 0;
}

From what I was able to gather.

Advantages of functors:
1. Functors can be inlined by the compiler, since the compiler can see it – unlike function pointers which carry a runtime cost(that’s the case usually – but there are exceptions).

2. It can have state, something that normal functions cannot have.

Disadvantages of functors:
1. Complex and longer to code – of course many might disagree on the ‘complex’ part – but longer for sure

2. Takes up more space – compared to a simple function.

Advertisements
Standard

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s