My function template has (among others) a function pointer (or a member function pointer) parameter. The function pointer may take any arguments, the argument types are being inferred. At the end of the parameter list, I want the function template to take the same parameters as the function pointer parameter.
template<typename R, typename... Args>
void f(R(*fp)(Args...), Args... args);
The problems begin when the argument types do not match perfectly, e.g. let’s say fp takes a Base* and the caller to f gives you a Derived* or fp takes a double and the caller puts in 0 (of type int).
Is there any way to tell the compiler to infer Args solely based on fp and “just use” those inferred types for args and not try to match them based on the arguments they bind to?
I found a solution that works. The term I did not know is non-deduced context. For example, everything to the left of the scope resolution operator
::is non-deduced. In C++20, you can usestd::type_identity_tto create such a context artificially, in C++14 and C++17, you can make your owntype_identity_t.So, you’d use
About perfect forwarding, when
fptakes an argument by reference or value,fwill do the same. Withstd::forward, a by-value parameter will be moved and a reference parameter will be referenced.