Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can C++ functors be preferable to objects with named methods?

I recently have got excited by functors and been using them all over the place. Then the situation arose where I needed my functor to perform two different operations and I thought about adding another method to my functor (not overloading the () operator). Whether this is bad practice or not I am not sure (perhaps you could tell me), but it got me thinking about why I am using functors in the first place and not just objects. So my question is:

Is there anything special about overloading the () operator or is it just very slightly more syntactically appealing than using normal named methods?

Update:

Firstly, I know why functors may be preferable to function pointers as explained in other questions. I want to know why they can be preferable to objects with named methods.

Secondly, as for an example of when I wanted to use another possibly named method of my functor: Basically I have two functions, one which calculates something called the modularity of a graph partition - compute_modularity(), and another which computes the gain in modularity after some change of the partitioncompute_modularity_gain(). I thought I could pass these functions as part of the same functor into an optimisation algorithm, with the gain as a named function. The reason I don't just pass two functors into the algorithm, is that I want to enforce that compute_modularity_gain() is used only in conjuction with compute_modularity() and not another functor e.g. compute_stability() (which should only be used with compute_stability_gain(). In other words, the gain function must be tightly coupled with its sibling function. If there is another way I can enforce this constraint then please let me know.

like image 869
zenna Avatar asked Apr 05 '11 00:04

zenna


Video Answer


1 Answers

The reason for the overload of operator() is to make functors have the same call semantics as function pointers -- and in fact you can use function pointers if you so desire.

There are a few reasons for overloading operator() instead of using a function -- but the most important one is that compilers will rarely optimize away the indirect function call when using a function pointer, but they'll almost always optimize away the operator() call -- this is why std::sort usually beats std::qsort.

There are a whole bunch of complicated reasons for this but what it really boils down to is that most (no?) compilers implement the optimization possible of removing the function pointer call, which is expensive on modern hardware.

Then the situation arose where I needed my functor to perform two different operations

Then it's no longer a functor. Either pass two functors to do what you want, or define a template method class. (You could also use mixins to achieve the template method pattern in C++ without runtime overhead -- but the Wikipedia article doesn't cover this) (Note also: Not the same as C++ templates, though C++ templates can be involved if you go the AOP route)

like image 119
Billy ONeal Avatar answered Sep 18 '22 09:09

Billy ONeal