The behaviour of this code is explained by C++14 [temp.deduct.call]:
Deducing template arguments from a function call
Template argument deduction is done by comparing each function template parameter type (call it P
) with the type of the corresponding argument of the call (call it A
) as described below
and then below:
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;
For the call f(array);
, we have A
= int[27]
. A
is an array type. So the deduced type T
is int *
, according to this last bullet point.
We can see from the qualifier "If P
is not a reference type" that this behaviour could perhaps be avoided by making P
a reference type. For the code:
template<typename T, size_t N>
void f(T (&x)[N])
the symbol P
means T(&)[N]
, which is a reference type; and it turns out that there are no conversions applied here. T
is deduced to int
, with the type of x
being int(&)[N]
.
Note that this only applies to function templates where the type is deduced from the argument. The behaviour is covered by separate parts of the specification for explicitly-provided function template parameters, and class templates.