Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

State data in functor members vs global function

When comparing functions and functors, it is often mentioned that one advantage of a functor over a function is that a functor is statefull.

However, in this code, it seems to me that a function may be statefull too. So what I am doing/understanding wrong?

struct Accumulator
{
  int counter = 0;
  int operator()(int i)
  { 
    counter += i; 
    return counter;
  }
};

int Accumulate(int i)
{
  static int counter = 0;
  counter += i;

  return counter;
};

int main()
{
  Accumulator acc;
  std::vector<int> vec{1,2,3,4};
  Accumulator acc2 = std::for_each(vec.begin(), vec.end(), acc);
  int d1 = acc(0); // 0, acc is passed by value
  int d2 = acc2(0); // 10

  std::for_each(vec.begin(), vec.end(), Accumulate);
  int d4 = Accumulate(0); // 10

  return 0;
}
like image 706
Korchkidu Avatar asked Jun 13 '14 16:06

Korchkidu


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.

Why use functor?

Functors give you more flexibility, at the cost of usually using slightly more memory, at the cost of being more difficult to use correctly, and at the cost of some efficiency.

How does a functor work?

A functor (or function object) is a C++ class that acts like a function. Functors are called using the same old function call syntax. To create a functor, we create a object that overloads the operator(). The line, MyFunctor(10); Is same as MyFunctor.


1 Answers

Each instance of a functor has its own state, while the static member of a function would be shared.

If you called for_each multiple times with the Accumulate() method, the counter would never reset, and each subsequent call would begin where the previous call ended. The functor would only have this behavior if each instance was reused. Creating a new functor would solve the problem.

like image 125
Dan Shield Avatar answered Nov 14 '22 21:11

Dan Shield