Open hubert-reinterpretcast opened 9 years ago
I don't think it's obvious that this should work. The substitution of <0>
into foo doesn't give zip
, due to 14.8.1/9; it gives something with a character more like this hypothetical thing:
template<int ...RestOfN = {}, typename T> void zip2({A<0> *, A<RestOfN>...}, T);
The A<RestOfN>...
parameter pack is a non-deduced context. The standard doesn't say how to match up P/A pairs after such a situation.
Suppose we instead have this call:
foo<>(0);
If we take 14.8.2.1/1 literally, we have two P/A pairs, A<N>*
/ int
and T
/ (no argument), because the parameter pack special case doesn't apply, so deduction presumably fails.
If we want your example to work, I think 14.8.2.1/1 needs tweaking to say how to form P/A pairs after a function parameter pack that appears before the end of the parameter-declaration-list
, or for something (probably 14.8.1) to say how the partial-substitution-of-pack-into-template mechanism is supposed to work.
Extended Description
N3290 subclause 14.8.2 [temp.deduct] paragraphs 2 to 5 specifies that explicit template arguments are substituted into the type of the function template prior to template argument deduction. In the case below, Clang rejects the call to
foo
(but adding-DUSE_DEFAULT
makes it work, which seems to indicate that it understands that theA<N> *...
expands toA<0> *
). If substitution is performed on the type offoo
such thatA<N> *...
expands toA<0> *
, then the case offoo
/bar
should behave likezip
/zap
, but that it not the case with Clang.SOURCE (
<stdin>
):COMPILER INVOCATION:
ACTUAL OUTPUT:
EXPECTED OUTPUT:
Clean compile.
COMPILER VERSION INFO: