2

I surfed on the internet and found different ways of counting a number in every function call.

1. Using Functor

class count_number {
private:
     int number;
public:
     count_number(): number{1} {}
     void operator()() {
          std::cout << "Number " << number++ << '\n';
     }
};
...
count_number counter;
counter();     
counter();
counter();

Outputs:

Number 1
Number 2
Number 3

2. Using Lambda

They said they resemble functors and the only difference is their mutability.

...
// Prior to C++ 23:
auto counter = [number = 1]() mutable { std::cout << "Number " << number++ << '\n'; }; 
counter();
counter();
counter();

Outputs exactly the same as above.

3. Using Static Variable

The variable number persists in every function call.

void counter() {
     static int number = 1;
     std::cout << "Number " << number++ << '\n';
}
...
counter();
counter();
counter();

Which still outputs exactly the same.

The questions are:

  • What are the pros and cons of the three ways in terms of memory efficiency, performance, and readability.
  • Which one do you think is the best and why? If none, what is it?
  • What's the point of having static variables inside a function aside from persisting data?
Desmond Gold
  • 1,517
  • 1
  • 7
  • 19
  • 2
    Can you provide your criteria for "best"? You're essential asking "what's the best way to create non-pure functions," which as far as I know has no objective answer. – Brian61354270 Apr 17 '21 at 03:24
  • 1
    Somewhat related: [Lambda Expression vs Functor in C++](https://stackoverflow.com/questions/4686507/lambda-expression-vs-functor-in-c) and [When to use functors over lambdas](https://stackoverflow.com/questions/27256062/when-to-use-functors-over-lambdas) – Brian61354270 Apr 17 '21 at 03:29

2 Answers2

3

What are the pros and cons

    • pro: Works pre-C++11. A named class supports more complex use cases not available to lambdas. Doesn't use static state.
    • con: Lots of boilerplate.
    • pro: Less boilerplate than 1. Doesn't use static state.
    • con: Doesn't work pre-C++11. Not as flexible as a named class.
    • pro: Simple. Works pre-C++11.

    • con: Uses static state, which as the name implies is not very flexible and can be problematic. For example, the following use case would require defining identical function multiple times which is unnecessary in cases 1. and 2.:

      count_number counter1;
      counter1();
      counter1();
      count_number counter2;
      counter2();
      counter2();
      

Which one do you think is the best and why? If none, what is it?

None, because each have pros and cons and "best" depends on which pros and cons apply to your specific use case and preferences. 3. is most problematic due to using static state.

What's the point of having static variables inside a function aside from persisting data?

The point of having static local variables is to persist data. There is no "aside".

eerorika
  • 232,697
  • 12
  • 197
  • 326
1

Two other big advantages of the Functor:

  • It's easy to declare multiple counters and have them count separately if you ever want that.
  • It's easy to add other member functions. You could have counter.reset() or counter.get().

If you're confident neither of these is going to be relevant, keep it simple with the static local variable.

dspeyer
  • 2,904
  • 1
  • 18
  • 24