Callback Dispatch: std::function vs Template Parameter
Question 15 / 17 • Correct so far: 0 (0 answered)
Std Function Callback
int accumulate(const std::vector<int>& v,
const std::function<int(int, int)>& fn) {
int acc = 0;
for (int x : v) acc = fn(acc, x);
return acc;
}
int result = accumulate(values, add); Template Callback
template <typename Fn>
int accumulate(const std::vector<int>& v, Fn fn) {
int acc = 0;
for (int x : v) acc = fn(acc, x);
return acc;
}
int result = accumulate(values, add); Shared test data (shared-setup)
constexpr int kN = 1024;
static std::vector<int> values(kN);
struct ValuesInit {
ValuesInit() { std::iota(values.begin(), values.end(), 1); }
} _values_init; Which snippet is faster?
Snippet B is faster. std::function uses type erasure to store any callable behind a uniform interface, which requires an indirect (virtual-like) call through a function pointer stored in the wrapper. For small callables the invocation overhead comes from that indirect dispatch; for larger callables there is an additional heap allocation. A template parameter lets the compiler see the exact callable type at compile time, enabling direct inlining of the lambda body into the loop — eliminating the indirect call entirely and allowing further loop-level optimisations such as auto-vectorisation.
Benchmark results
| Snippet | CPU time / iteration | Speedup |
|---|---|---|
| Std Function Callback | 1.4 us | 1.0× |
| Template Callback | 21 ns | 66.7× |
Explore the source
Open in Compiler ExplorerQuiz complete. You can return to the question list to restart and compare.