0

I am trying to understand cases that require using functors. Most of the answer on Stackoverflow and other websites put emphasis on being able to define different adders or multipliers regarding benefits of functors.

Can the use of functors go beyond them? What are some other uses of functors?

Erdem Tuna
  • 500
  • 4
  • 18
  • 2
    What specifically does not satisfy you in the explanations in e.g. https://stackoverflow.com/questions/356950/what-are-c-functors-and-their-uses? All the standard algorithms use functors like in the examples provided there. Also note that since C++11, functors are mostly replaced by (or rewritten as) lambda expressions. – walnut Dec 17 '19 at 06:04
  • The answers are just another version of one another and I wondered if there are any other examples? – Erdem Tuna Dec 17 '19 at 06:18
  • Read about the C++11 lambda expressions (which are functors in convenient disguise), functional programming in general and, in particular, "closures" in functional programming. – molbdnilo Dec 17 '19 at 06:19

1 Answers1

1

More often than not, functors are used with other API calls that need some kind of function object. For example, sorting vectors of user-defined objects which don't have operator() or operator< (etc.) defined.

There are some cases where a set of functors may prove useful. One such case comes when you have several algorithms which functionally do the same thing, but achieve varying levels of accuracy. This happens a lot with some numeric optimization problems: given the general form of a matrix, we might use a different technique to find the solution of a linear equation (e.g., sparse vs dense problem-matracies can employ different algorithms to invert the matrix).

In particular, you should consider functors versus lambdas. In modern versions of C++, there really isn't a need to specify a functor unless you're implementing a function/method that needs a functor (or lambda) as an argument. There are some cases to consider: Do you need a unit-test? Is the functor itself a prototype of future functionality? etc.

ADDENDUM: The key thing to consider is that the use of functor/lambda ultimately boils down to a design decision. As @t.niese noted in the comments, you could use just use functions in combination of template arguments. In addition to the previous considerations above, consider whether or not you can make a compile-time or run-time assessment of the needed functionality.

Additionally, as you make design decisions, you may want to consider "Is there a need for this function to be used outside of this specific context?" If the answer is no, that's a compelling argument to choose a lambda over a free function. With regards to functor specifically, this was an important pattern added before the addition of lambdas to the standard. Typically they're defined in a somewhat private context (frequently in the implementation files, thus after compiled into a library, obfuscated to users of the API). Now with lambdas, you can simply define them within another function or even as a function argument, instead of pre-defining them prior to need.

jhill515
  • 894
  • 8
  • 26
  • This does not really explain when and why a functor is needed. `One such case comes when you have several algorithms which functionally do the same thing, but achieve varying levels of accuracy` Why can’t I use a set of free function, and the accuracy is controlled by template arguments? – t.niese Dec 17 '19 at 06:16
  • To answer your question specifically, @t.niese, there's no reason why you cannot do so. Ultimately it boils down to design decisions, consideration of algorithmic & architectural evolution, and finally requirements posed by leadership, customers, and regulations (there are some safety-critical coding standards which strictly prohibit function templatization and functors, not well justified IMHO, but regulations nonetheless). – jhill515 Dec 17 '19 at 14:51
  • 1
    What I wanted to say with my comment, is that this example might not be the best to illustrate where a functor or lambda has advantages over a normal function callback. Functors and Lambdas can carry modifiable states that depend on runtime data, this can - in many cases - not be solved in a comfortable and nice way using only simple callbacks. – t.niese Dec 17 '19 at 15:20