I came across the following statement in the standard:
If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a pack ([dcl.fct]), then the template-parameter is a template parameter pack. A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded packs is a pack expansion. ... A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same template-parameter-list.
(end quote)
So consider the following invalid example:
template<typename... Ts, Ts... vals> struct mytuple {}; //invalid
The above example is invalid because the template type parameter pack Ts
cannot be expanded in its own parameter list.
Are the below given examples valid/invalid?
Then i tried the same with function templates and expected the same result but to my surprise it compiles fine in gcc & clang but not in msvc. The example is as follows:
//is this valid?
template<typename... T, T... ar>
void func(){}
int main()
{
}
Similarly, the below given example compiles in gcc and clang but not in msvc:
//is this valid?
template<typename...T, int (*FUNC)(T...)>
int wrapper(T... args) { return (*FUNC)(args...) * 10; }
int main()
{
}
Which compiler is right here? That is, does the quoted statement temp.param#17 applies to the given two examples and so they are invalidated or is the quote not applicable to the given two examples.
It's a bug in GCC and Clang. You wrote clearly-defined-as-invalid code, MSVC correctly throws an error while gcc and clang do not. Therefore MSVC is correct. GCC and Clang are not.
As an aside, I ran the code snippets in MSVC C++20 mode and the same error was still thrown. It's been correctly handled since C++14 in MSVC and a bug in GCC and Clang for just as long.