The definition of the template S
, and the instantiation of S<int, char>
, are valid.
See [temp.param]/15: "A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded parameter packs is a pack expansion."
This means that template<T ...I>
can mean one of two different things: if T
is a non-pack type, then it declares a normal parameter pack, accepting any number of T
s. However, if T
contains an unexpanded parameter pack, then the parameter declaration is instead expanded into a sequence of parameters when the outer template is instantiated.
Your first call to m
is valid, but your second and third calls to m
are ill-formed
The instantiation of S<int, char>
looks like this:
template<>
struct S<int, char> {
template<int I$0, char I$1>
void m() {}
};
(where I$0
and I$1
are the first and second slices of the pack I
).
Therefore (because neither I$0
nor I$1
can be deduced from a call to m
), s.m<0,'c'>()
is valid but s.m<0>()
and s.m<>()
are ill-formed.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…