コンパイラーは、境界が参照またはポインター型を参照しない限り、主配列の境界の値を推定できません。
主配列の境界は、関数仮パラメーター型の一部ではありません。
次のコードは、このことを示しています。
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); }
コンパイラーは、呼び出し g(c) を許可しません。 コンパイラーは、テンプレート引き数 i を推定できません。
コンパイラーは、テンプレート関数のパラメーター・リストの式で使用されている、 「非型」テンプレート引き数の値を推定できません。 次の例は、このことを示しています。
template<int i> class X { }; template<int i> void f(X<i - 1>) { }; int main () { X<0> a; f<1>(a); // f(a); }
関数 f() をオブジェクト a で呼び出すためには、 関数が、型 X<0> の引き数を受諾する必要があります。 しかし、コンパイラーは、X<i - 1> が X<0> と同等であるためには、 テンプレート引き数 i が、1 と等しい必要があるということを推定できません。 したがって、コンパイラーは、関数呼び出し f(a) を許可しません。
コンパイラーに「非型」テンプレート引き数を推定させたい場合、 パラメーターの型が、関数呼び出しで使用される値の型と正確に一致しなければなりません。 例えば、コンパイラーは、次の表記を許可しません。
template<int i> class A { }; template<short d> void f(A<d>) { }; int main() { A<1> a; f(a); }
例で f() を呼び出す場合、コンパイラーは、int を short に変換しません。
しかし、推定された配列の境界は、整数型になります。
関連参照