Given overloaded functions f1
:
void f1(int);
int f1(char);
And a class template X
with member template f
:
template<class T>
struct X
{
template<class U>
static void f(T(*p)(U));
};
The compiler is able to resolve f1
from part of the function type:
X<int>::f(f1); // T = int (specified), U = char (deduced)
X<void>::f(f1); // T = void (specified), U = int (deduced)
However, a variadic class template Y
with parameter pack at both sides:
template<class... T>
struct Y
{
template<class... U>
static void f(T(*...p)(U));
};
Fail to do the same thing:
Y<int>::f(f1); // error
Y<void>::f(f1); // error
Y<int, void>::f(f1, f1); // error
Note that it's OK if the parameter pack is only at one 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 a problem: the outer parameter pack T
cannot be expanded while the inner parameter pack U
is still dependant. I imagine the compiler could expand Y::f
to something like below when Y<int, void>
is instantiated:
template<class... U>
void f(int(*p0)(U0), void(*p1)(U1));
where U0
and U1
denote the first 2 elements of parameter pack U
.
But it seems that compilers(g++/clang) refuse to do so and leave the whole p
unexpended. where in the standard does it specify such a behavior? Could it be a standard defect or something to improve?
Aucun commentaire:
Enregistrer un commentaire