http://gcc.gnu.org/bugzilla/show_bug.cgi?id=50839
Daniel Krügler <daniel.kruegler at googlemail dot com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |daniel.kruegler at | |googlemail dot com --- Comment #1 from Daniel Krügler <daniel.kruegler at googlemail dot com> 2011-10-23 21:30:05 UTC --- According to [dcl.fct] p5, "any parameter of type “array of T” or “function returning T” is adjusted to be “pointer to T” or “pointer to function returning T,” respectively. [..] The resulting list of transformed parameter types and the presence or absence of the ellipsis or a function parameter pack is the function’s parameter-type-list." This has the effect that void f4(int* x); and void f4(int x[4]); are essentially equivalent declarations of the same function. The same rationale applies to template<class... T> void f2(int* x, T... y); versus template<class... T> void f2(int x[4], T... y); so in sample1 you are violating the ODR two times in a form that requires a diagnostic. This rationale cannot be applied directly to templates, because due to SFINAE you could render one instantiation invalid (e.g. when attempting to instantiate an array of zero or negative size) and it is allowed for two different function template specializations to have the same type ([temp.over.link] p1). But according to [temp.deduct.call] p2: "If P is not a reference type: — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction;" This has basically the effect that an example like template<class T, int N> void g(T x[N]) {} int main() { int a[4]; g(a); } can never be well-formed, because N cannot be (implicitly) deduced from an effective argument of type int*. This explains the effect that the template examples alway select the pointer overload, not the array overload. So, from what I see so far this issue is invalid.