I think, the main point was missed in the discussion here so far. First of all, the test code won't even compile due to syntax errors. Probably, the following was meant:
template<typename OP>
int do_op(int a, int b, OP op) { return op(a,b); }
int add(int a, int b) { return a + b; }
int (*func_ptr)(int, int) = add;
int c = do_op(4, 5, func_ptr);
// int c = (*func_ptr)(4, 5);
When compiled, the compiler will issue code for actually calling the add() function. However, when written without the template as int c = (*func_ptr)(4, 5);
, the compiler will also issue a call to add(). This is, because func_ptr
is defined global in this sample code, and the compiler has to care for the possibility, that some code in another thread modifies func_ptr between its initialization and its subsequent use. But this is a property of the globally visible function pointer, and has nothing to do with the template! Except for the name of some local labels, GCC with optimizer on produces exactly the same assembler output for both the templated and non-templated call to add() via func_ptr. The different label name means, that the optimizer has to turn an extra round because of the template, so compile time increases (like with all templates), but code and thus also code run time is identical.
If func_ptr is moved to a local variable inside a function, as in the following example, the compiler can for sure trace all accesses to func_ptr, and as a result optimize out everything and even no longer call the add() function, neither directly nor through the function pointer:
int testf(void) {
int (*func_ptr)(int, int) = add;
return do_op(4, 5, func_ptr);
}
So, to sum up things: Function calls via templates don*t stop the optimizer from doing its work. Function pointers can do harm, if their value cannot be determined safely at compile time, but that problem is not worsened, if a template is added.