名前のバインディング は、
テンプレートで明示的に、または暗黙的に使用されている名前ごとに宣言を検出する処理です。
コンパイラーは、テンプレートの定義で名前をバインドしたり、またはテンプレートのインスタンス化のときに名前をバインドします。
従属名 は、テンプレート・パラメーターの型、 または値に依存する名前です。 次に例を示します。
template<class T> class U : A<T> { typename T::B x; void f(A<T>& y) { *y++; } };
この例では、従属名は、基底クラス A<T>、型名 T::B、 および変数 y です。
テンプレートのインスタンスが作成されると、コンパイラーは、従属名をバインドします。 テンプレートが定義されると、コンパイラーは、非従属名をバインドします。 次に例を示します。
void f(double) { cout << "Function f(double)" << endl; } template<class T> void g(T a) { f(123); h(a); } void f(int) { cout << "Function f(int)" << endl; } void h(double) { cout << "Function h(double)" << endl; } void i() { extern void h(int); g<int>(234); } void h(int) { cout << "Function h(int)" << endl; }
関数 i() を呼び出すと、以下が出力されます。
Function f(double) Function h(double)
テンプレートの定義のポイント は、それの定義の直前に配置されます。
この例では、関数テンプレート g(T) の定義のポイントは、 キーワード template の直前に配置されます。 関数呼び出し f(123) は、テンプレート引き数に依存しないので、 コンパイラーは、関数テンプレート g(T) の定義の前に宣言された名前を考慮に入れます。 したがって、呼び出し f(123) は、f(double) を呼び出します。 f(int) のほうがうまく当てはまりますが、 それは、g(T) の定義のポイントのあるスコープ内に存在していません。
テンプレートのインスタンス化のポイント は、その使用を囲む宣言の直前に配置されます。
この例では、g<int>(234) 呼び出しのインスタンス化のポイントは、 i() の直前に配置されます。 関数呼び出し h(a) はテンプレート引き数に依存するので、コンパイラーは、関数テンプレート g(T) のインスタンス化の前に宣言された名前を検討します。 したがって、h(a) の呼び出しは、h(double) を呼び出します。 h(int) は g<int>(234) のインスタンス化のポイントのあるスコープ内になかったため、コンパイラーは、この関数を検討しません。
インスタンス化バインディングのポイントは、次の意味を持ちます。
関連参照