I have tried to construct a case that requires no typename or template, but still yield a variable or template depending on whether a given name t is a function parameter pack or not
template<typename T> struct A { template<int> static void f(int) { } };
template<typename...T> struct A<void(T...,...)> { static const int f = 0; };
template<typename> using type = int;
template<typename T> void f(T t) { A<void(type<decltype(t)>...)>::f<0>(1); }
int main() {
f(1);
}
The above will refer to the static const int, and do a comparison. The following just has T t changed to be a pack and make f refer to a template, but GCC does not like either
template<typename ...T> void f(T ...t) { A<void(type<decltype(t)>...)>::f<0>(1); }
int main() {
f(1, 2, 3);
}
GCC complains for the first
main.cpp:5:68: error: incomplete type 'A<void(type<decltype (t)>, ...)>' used in nested name specifier
template<typename T> void f(T t) { A<void(type<decltype(t)>...)>::f<0>(1); }
And for the second
main.cpp:5:74: error: invalid operands of types '<unresolved overloaded function type>' and 'int' to binary 'operator<'
template<typename ...T> void f(T ...t) { A<void(type<decltype(t)>...)>::f<0>(1); }
I have multiple questions
- Does the above code work according to the language, or is there an error?
- Since Clang accepts both variants but GCC rejects, I wanted to ask what compiler is correct?
If I remove the body of the primary template, then for the
f(1, 2, 3)case, Clang complainsmain.cpp:5:42: error: implicit instantiation of undefined template 'A<void (int)>'Please note that it says
A<void (int) >, while I would expectedA<void (int, int, int)>. How does this behavior occur? Is this a bug in my code - i.e is it illformed, or is it a bug in Clang? I seem to remember a defect report about the order of expansion vs the substitution of alias template, is that relevant and does it render my code ill-formed?
void(T...,...)looks likeT...is in non deduce context but I'm not sure how compiler should react...Tbecause then I'm not sure howis_functionshould detect them.templatebetween::andfin the case wherefis atemplate?type<dependent-type>is not dependent if it'stemplate<typename> using type = int;, but I could be wrong. See open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1390 . When asking this question, I forgot about that DR I made long ago, but now I see that actually, it has not been resolved yet. The committee only clarified that they want it to be non-dependent. Apart from that, however, is anything else wrong with my snippet?