The compiler cannot deduce the value of a major array bound unless the bound refers to a reference or pointer type. Major array bounds are not part of function parameter types. The following code demonstrates this:
template<int i> void f(int a[10][i]) { };
template<int i> void g(int a[i]) { };
template<int i> void h(int (&a)[i]) { };
int main () {
int b[10][20];
int c[10];
f(b);
// g(c);
h(c);
}
The compiler would not allow the call g(c); the compiler cannot deduce template argument i.
The compiler cannot deduce the value of a non-type template argument used in an expression in the template function's parameter list. The following example demonstrates this:
template<int i> class X { };
template<int i> void f(X<i - 1>) { };
int main () {
X<0> a;
f<1>(a);
// f(a);
}
In order to call function f() with object a, the function must accept an argument of type X<0>. However, the compiler cannot deduce that the template argument i must be equal to 1 in order for the function template argument type X<i - 1> to be equivalent to X<0>. Therefore the compiler would not allow the function call f(a).
If you want the compiler to deduce a non-type template argument, the type of the parameter must match exactly the type of value used in the function call. For example, the compiler will not allow the following:
template<int i> class A { };
template<short d> void f(A<d>) { };
int main() {
A<1> a;
f(a);
}
The compiler will not convert int to short when the example calls f().
However, deduced array bounds may be of any integral type.