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