views:

211

answers:

5

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 { 
private: 
  int n;
public: 
  void operator ()() const; 
};

And then use it this way:

A a;
a() ;

In what case can this be consider useful ?

+1  A: 

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

Reed Copsey
+7  A: 

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.

Greg Hewgill
And the main reason you'd want functors is to have higher-order functions in C++.
Harold L
No, it prints something like "Error: You forgot to declare a private variable in your class." At least, that's what the fictional compiler in my head prints.
Chris Lutz
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.
MatrixFrog
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)
Michael Anderson
@Chris Lutz: Sorry, Safari crashed on me. Fixed now.
Greg Hewgill
+2  A: 

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.

paul
A: 

this can be made use in typecasting function rite? where there are 2 types of typecasting 1)from source 2)from destination

double b; int a=(int)b;

or

int a=int(b);

I'm not sure if you're right about that but casting is not the same thing as overloading the () operator.
MatrixFrog
Eugen Constantin Dinca
+5  A: 

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 my_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) );
Michael Anderson