Here is a minimal example triggering the compilation error:
#include <utility>
void foo(int, double, int)
{}
template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
{
fun(std::forward<Args>(aArgs)..., 5);
}
int main()
{
post_forwarder(foo, 6, 6.1); // Compilation error on instantiation
return 0;
}
I suspect the problem is related to the fact that the variadic template parameter is expanded in the function type before the fixed int parameter, but if it is the case I cannot find a good rationale for it.
The error reported by Clang 3.6 is:
error: no matching function for call to 'post_forwarder'
note: candidate template ignored: failed template argument deduction
Argument deduction fails here:
template <class... Args>
void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs)
// ^^^^^^^
for the general rule that parameter packs have to be at the end to be deducible. The usual solution is to wrap it in a non-deducible context, so that deduction isn't even attempted:
template <typename T>
struct identity {
using type = T;
};
template <class... Args>
void post_forwarder(void(*fun)(typename identity<Args>::type..., int), Args&&... aArgs)
{
fun(std::forward<Args>(aArgs)..., 5);
}
This works:
template <class F, class... Args>
void post_forwarder(F f, Args&&... aArgs) {
f(std::forward<Args>(aArgs)..., 5);
}
LIVE DEMO
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With