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?
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.