2

The advantage of functors with respect to functions is said to be that they keep a state. Let's say in my problem this is not a relevant feature.

When I am defining a templated function/class, is there any rule for choosing if it would be better to have a function or a functor as template parameter? Or can I basically do the same thing, so does it depend on my taste?

(Related question: Functor vs template parameters)

Edit:
My question is partially answered (for the user side) here: Reason to use this stateless class with a function call operator vs a c style function?

Community
  • 1
  • 1
Antonio
  • 19,451
  • 13
  • 99
  • 197

1 Answers1

6

Since you are defining a template function, don't impose a choice on your users (if it was not a template, I would suggest that you made it a template for this reason anyways).

Note that there are two sides of an interface. The function you are defining gets to choose the signature, but it does not know whether the caller (user of the function) will want to keep state. If you opted for a function pointer, then the function being defined would impose a requirement on the users, reducing flexibility.

Remember that C++ is a really nice language in that it allows you to provide abstraction with little or no cost in many cases. For example, if you opt to use a generic approach like:

template <typename Iterator, typename Pred>
std::find_if( Iterator first, Iterator last, Pred p );

That allows for functors with state, it can still be used with plain functions without any loose of performance. The generic approach will not be worse than the manually handcrafted solution.

David Rodríguez - dribeas
  • 204,818
  • 23
  • 294
  • 489
  • 3
    @Antonio: I think you misunderstand it. You can use function pointers in most algorithms of the standard library. As in the example above, there is nothing limiting you from passing a free function that takes the appropriate arguments and returns `bool`. And more importantly, if you decide to pass a function pointer, it won't be less performing than if it had been designed with just function pointers in mind. Note that in the code above, the requirements of `Pred` is *callable* with two `Iterator::value_type`, not *functor* implementing `operator()` with... – David Rodríguez - dribeas Jul 25 '13 at 13:14
  • And, just to fully address my question: is there any specific reason for which my user (which often happen to be still myself :) ) should choose to pass a function or a functor, if the state is not important? – Antonio Jul 25 '13 at 13:36
  • @Antonio: I thought I answered that: *don't impose the choice on your users* make it a template argument. – David Rodríguez - dribeas Jul 25 '13 at 13:49
  • @Antonio: The question you link is from the user point of view, given a function that is declared to take a generic callable entity, should I prefer to pass a function pointer or a functor? Your question here is about the design of the function's interface: should I impose the use of a function pointer or leave it generic and allow functors? (writting a function that took a *functor* but rejected a function pointer would be cumbersome, although possible) – David Rodríguez - dribeas Jul 25 '13 at 13:52
  • I did a further edit sorry, that answer only partially my question, the rest of the answer is provided by your answer. One point is also that I could not find the other question before, and I think also that that question is difficult to find because of the title (no template mentioning) and the incomplete tags. – Antonio Jul 25 '13 at 13:56
  • _don't impose a choice on your users_ makes it a template argument, either directly or indirectly: you could use `std::function`. Not as efficient as a straightforward template, though. – MSalters Jul 25 '13 at 14:04
  • @MSalters: I would not go that way. There you are imposing a cost, and inhibiting the possibility of inlining even if the argumet is a functor. Basically you get the worst of both worlds plus an extra allocation. `std::function<>` is a good *vocabulary type* if you need one, and needed if you want to store a generic *callable* (function/functor) – David Rodríguez - dribeas Jul 25 '13 at 14:29