In the following example:
template<class... T>
struct S
{
template<class... U>
static void f(T(*...p)(U));
};
template<class... T, class... U>
void f(T(*...p)(U));
Intuitively, I expect
S<int, void>::f would be expanded to something like:
template<class... U>
void S<int, void>::f(int(*p$0)(U$0), void(*p$1)(U$1));
and
f<int, void> would be:
template<class... T, class... U>
void f<int, void>(int(*p$0)(U$0), void(*p$1)(U$1), T(*...p)(U));
If pack expansion works this way, we should be able to do:
// Some overloaded functions
void f1(int);
int f1(char);
// Non-overloaded function
void f2(int);
// Case A - These should work.
S<int>::f(f1);
S<void>::f(f1);
S<int, void>::f(f1, f1);
// Case B - These should work too.
f<int>(f1);
f<void>(f1);
f<int, void>(f1, f1, f2); // f2 extends the explicitly specified template args
Unfortunately, it doesn't work that way. Clang rejects both case A & B, GCC accepts only case B.
I'm not familiar with the standard wording. Is it possible to refine pack expansion as illustrated above?