c++ - Can outer parameter pack be expanded with inner parameter pack to be deduced? -


given overloaded functions f1:

void f1(int); int f1(char); 

and class template x member template f:

template<class t> struct x {     template<class u>     static void f(t(*p)(u)); }; 

the compiler able resolve f1 part of function type:

x<int>::f(f1); // t = int (specified), u = char (deduced) x<void>::f(f1); // t = void (specified), u = int (deduced) 

however, variadic class template y parameter pack @ both sides:

template<class... t> struct y {     template<class... u>     static void f(t(*...p)(u)); }; 

fail same thing:

y<int>::f(f1); // error y<void>::f(f1); // error y<int, void>::f(f1, f1); // error 

note it's ok if parameter pack @ 1 side:

template<class... t> struct z1 {     template<class u>     static void f(t(*...p)(u)); };  template<class t> struct z2 {     template<class... u>     static void f(t(*...p)(u)); };  z1<int>::f(f1); // ok z2<void>::f(f1); // ok 

this showns problem: outer parameter pack t cannot expanded while inner parameter pack u still dependant. imagine compiler expand y::f below when y<int, void> instantiated:

template<class... u> void f(int(*p0)(u0), void(*p1)(u1)); 

where u0 , u1 denote first 2 elements of parameter pack u.

but seems compilers(g++/clang) refuse , leave whole p unexpended. in standard specify such behavior? standard defect or improve?

i've extracted code snippet works, although still doesn't satisfies needs, may lead something:

void f1(int) {  }  int f1(char) {     return 0; }  template <class out, class in> struct unifunction {     typedef out fn(in);     typedef fn* ptr; };  template<class... t> struct y {   //template<class... u>   //static void f(t(*...p)(u)...);     template <class... u>     struct yy     {         static void f(typename unifunction<t, u>::ptr...)         {          }     };   };  int main( int argc, char** argv ) {      y<int>::yy<char>::f(f1);      return 0; } 

this unifunction clarity , maybe show double parallel expansion of parameter pack isn't impossible, there's small problem.

i think can still enforce argument type deduction if provide additionally "template function" (structure template typedefs) extract (using type_traits or something) argument type , return type function pointer. having that, should able provide y::f function 1 template parameter (kinda x...), extract argument type x being function pointer, pass explicitly yy template, shown here.


Comments