Passing functions in C++
The only runtime cost of
template<typename F>
void call100(F&& f) {
for (int i = 0; i < 100; ++i)
f();
}
is that it can have more versions (copies of code) if you pass f
in multiple ways. With MSVC or the gold linker with ICF, those copies only cost compile time unless they differ, and if they differ you probably want to keep them.
template<typename F>
void call100(F f) {
for (int i = 0; i < 100; ++i)
f();
}
this one has the advantage of being value semantics; and following the rule of taking values unless you have good reason not to is reasonable. std::ref
/std::cref
let you call it with a persistant reference, and for prvalues c++17 guaranteed elision will prevent a spurious copy.
As a joke you could do:
template<typename F>
void call100(F&& f) {
for (int i = 0; i < 99; ++i)
f();
std::forward<F>(f)();
}
but that relies on people having &&
overloads on their operator()
, which nobody does.
I would use the first one (pass the callable by value).
If a caller is concerned about the cost of copying the callable, then they can use std::ref(f)
or std::cref(f)
to pass it using reference_wrapper
.
By doing this, you provide the most flexibility to the caller.