How can it be useful to overload the "function call" operator?

21,513

Solution 1

This can be used to create "functors", objects that act like functions:

class Multiplier {
public:
    Multiplier(int m): multiplier(m) {}
    int operator()(int x) { return multiplier * x; }
private:
    int multiplier;
};

Multiplier m(5);
cout << m(4) << endl;

The above prints 20. The Wikipedia article linked above gives more substantial examples.

Solution 2

There's little more than a syntactic gain in using operator() until you start using templates. But when using templates you can treat real functions and functors (classes acting as functions) the same way.

class scaled_sine
{
    explicit scaled_sine( float _m ) : m(_m) {}
    float operator()(float x) const { return sin(m*x); }
    float m;
};

template<typename T>
float evaluate_at( float x, const T& fn )
{
   return fn(x);
}

evaluate_at( 1.0, cos );
evaluate_at( 1.0, scaled_sine(3.0) );

Solution 3

A algorithm implemented using a template doesn't care whether the thing being called is a function or a functor, it cares about the syntax. Either standard ones (e.g. for_each()) or your own. And functors can have state, and do all kinds of things when they are called. Functions can only have state with a static local variable, or global variables.

Solution 4

If you're making a class that encapsulates a function pointer, this might make the usage more obvious.

Solution 5

The compiler can also inline the functor and the function call. It cannot inline a function pointer, however. This way, using the function call operator can significantly improve performance when it is used for example with the standard C++ libary algorithms.

Share:
21,513

Related videos on Youtube

lurks
Author by

lurks

Software developer. Geek. Hipster? I live in Argentina. Programming languages I find interesting: C++, Python, Lisp, Javascript, Clojure, and anything that runs on top of the JVM (but not the Java language itself though). I feel more comfortable under Unix environments.

Updated on July 09, 2022

Comments

  • lurks
    lurks almost 2 years

    I recently discovered that in C++ you can overload the "function call" operator, in a strange way in which you have to write two pair of parenthesis to do so:

    class A { 
      int n;
    public: 
      void operator ()() const; 
    };
    

    And then use it this way:

    A a;
    a();
    

    When is this useful?

  • Harold L
    Harold L about 14 years
    And the main reason you'd want functors is to have higher-order functions in C++.
  • Tyler
    Tyler about 14 years
    You could expand this to, for example, multiply by m the first time you call it, multiply by m+1 the second time, etc. Normal functions can't save any state information in between calls, but functors can.
  • Michael Anderson
    Michael Anderson about 14 years
    Well you can always use static variables in a function to give it state (or globals - shudder). But both are very ugly and error prone. (I'd use a functor instead .. but it is possible)
  • Adrian Ratnapala
    Adrian Ratnapala over 11 years
    Yep; function-like objects really are most useful when you have sufficiently weak typing. C++ hasn't got that, but templates do.