Why is this replacement of the template parameter variable not performed? (batch to fixed arguments)

Here is a minimal example that causes a 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 that the problem is that the parameter of the variational template is expanded in the function type to a fixed parameter int, but if so, I can not find a good justification for it.

Error reported by Clang 3.6:

 error: no matching function for call to 'post_forwarder' note: candidate template ignored: failed template argument deduction 
+5
source share
3 answers

The argument output is completed here:

 template <class... Args> void post_forwarder(void(*fun)(Args..., int), Args&&... aArgs) // ^^^^^^^ 

for the general rule that parameter packets must be at the end in order to be output. The usual solution is to wrap it in an inaccessible context, so that deduction doesn't even try:

 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); } 
+7
source

It works:

 template <class F, class... Args> void post_forwarder(F f, Args&&... aArgs) { f(std::forward<Args>(aArgs)..., 5); } 

Live demo

+1
source

Edit: Overwritten answer:

The form Args..., int does not allow the output of Args...

0
source

Source: https://habr.com/ru/post/1235904/


All Articles