Search code examples
c++11templateslambdacallable

What is the best type for a callable object in a template method?


Every time I write a signature that accepts a templated callable, I always wonder what the best type for the parameter is. Should it be a value type or a const reference type?

For example,

template <class Func>
void execute_func(Func func) {
    /* ... */
}

// vs.

template <class Func>
void execute_func(const Func& func) {
    /* ... */
}

Is there any situation where the callable is greater than 64bits (aka a pointer to func)? Maybe std::function behaves differently?


Solution

  • In general, I do not like passing callable objects by const reference, because it is not that flexible (e.g. it cannot be used on mutable lambdas). I suggest to pass them by value. If you check the stl algorithms implementation, (e.g. for std::for_each), all of the callable objects are passed by value as well.

    Doing this, the users are still able to use std::ref(func) or std::cref(func) to avoid unnecessary copying of the callable object (using reference_wrapper), if desired.