6
votes

[temp.param] p11 says (in N4527):

(...) 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 of the function template or has a default argument

In the context of non-type template parameter packs, there can't be default arguments,
so what exactly needs to be deduced for the packs (just the type, or the values, too)?

i.e. I'm wondering if this is allowed by the standard (C++11, 14 or 1z):

template<typename T, T... A, T... B>
void foo(T) {}

The first pack's values could be explicitly specified, but the second pack is "unreachable" and would always be empty if I'm not mistaken.

clang++-3.6 and g++-5.2 seem to accept these empty unreachable packs (even non non-type packs), but VC++ 14.0 refuses them with the error:

error C3547: template parameter 'B' cannot be used because it follows a template parameter pack and cannot be deduced from the function parameters of 'foo'

1
The values must be deducible. Surprising enough, MSVC is right. It looks like neither implements this check since neither diagnoses template<class... T, class... U> void f() { }, which the standard explicitly labels as "error".T.C.
I was hoping there'd be a loophole for non-type parameter packs :(melak47
Ugh, the standard needs fixing :S There's no reason to forbid this.R. Martinho Fernandes
@R.MartinhoFernandes What's the point of a template parameter that you can never supply an argument for?T.C.
@T.C. if that was the rationale, then there would be no exception for "or has a default argument". (I use those kinds of packs all the time; they're the best way to do SFINAE selection of overloads IMO)R. Martinho Fernandes

1 Answers

4
votes

No, it not allowed by the standard. From [temp.param]:

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 of the function template or has a default argument (14.8.2). [Example:

template<class T1 = int, class T2> class B;    // error

// U can be neither deduced from the parameter-type-list nor specified
template<class... T, class... U> void f() { }  // error
template<class... T, class U> void g() { }     // error

—end example ]

In your case, ...B cannot be deduced (as there's nothing to deduce it from) and it has no default argument.

so what exactly needs to be deduced for the packs (just the type, or the values, too)?

For example, if your foo was:

template <size_t... A, size_t... B>
void foo(std::index_sequence<B...> );

...A is followed by ...B, but ...B can be deduced, so that's allowed. Similarly:

template <typename T, T... A, T B = 0>
void foo();

is fine, as B has a default argument.