Reference (section label): [temp.param] paragraph 14
Issue description
There is implementation divergence in the following example:
template <class Head, class... Tail>
struct test {
template <Tail..., Head>
static void make() { } // MSVC error C3547: template parameter 'unnamed-parameter' cannot be used
// because it follows a template parameter pack and
// cannot be deduced from the function parameters of 'test<Head,Tail...>::make'
};
int main() {
test<char, int, float>::make<4, 6.f, 'a'>();
}
Clang permits this example, but MSVC abides by [temp.param] paragraph 14, sentence 3:
A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).
The intent of the restriction is that it is not permitted to write template parameter lists for which it is impossible to provide all arguments. However, [temp.param] paragraph 17 states that Tail... is not just a parameter pack but also a pack expansion. Considering that it expands to int, float in this example, following this restriction literally is nonsensical; it is clearly possible to provide (non-type) template-arguments to test<char, int, float>::make because it accepts exactly three.
Suggested resolution
Update [temp.param] paragraph 14 as follows:
A template parameter pack of a function template shall not be followed by another template parameter P unless
that template parameter P can be deduced from the parameter-type-list ([dcl.fct]) of the function template, or
- P has a default argument ([temp.deduct]), or
- that template parameter pack is also a pack expansion.
Reference (section label): [temp.param] paragraph 14
Issue description
There is implementation divergence in the following example:
Clang permits this example, but MSVC abides by [temp.param] paragraph 14, sentence 3:
The intent of the restriction is that it is not permitted to write template parameter lists for which it is impossible to provide all arguments. However, [temp.param] paragraph 17 states that
Tail...is not just a parameter pack but also a pack expansion. Considering that it expands toint, floatin this example, following this restriction literally is nonsensical; it is clearly possible to provide (non-type) template-arguments totest<char, int, float>::makebecause it accepts exactly three.Suggested resolution
Update [temp.param] paragraph 14 as follows: