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
Post a Comment