関数テンプレートの特殊化は、
テンプレート引き数の推定で、特殊化が複数の多重定義と関連付けられるので、あいまいになります。
そのため、コンパイラーは、最も特殊化された定義を選択します。
関数テンプレート定義を選択するこの処理は、部分選択 と呼ばれます。
X からの特殊化と一致する引き数リストは、どれも Y からの特殊化と一致するが、その逆では一致しないという場合は、テンプレート X は、テンプレート Y よりもさらに特殊化されています。次の例は、部分選択を示しています。
template<class T> void f(T) { } template<class T> void f(T*) { } template<class T> void f(const T*) { } template<class T> void g(T) { } template<class T> void g(T&) { } template<class T> void h(T) { } template<class T> void h(T, ...) { } int main() { const int *p; f(p); int q; // g(q); // h(q); }
宣言 template<class T> void f(const T*) は、 template<class T> void f(T*) よりもさらに特殊化されています。 したがって、関数呼び出し f(p) は、 template<class T> void f(const T*) を呼び出します。 しかし、void g(T) および void g(T&) はどちらも、 特殊化の程度には差はありません。したがって、関数呼び出し g(q) はあいまいになります。
省略符号は、部分選択に影響を与えません。 したがって、関数呼び出し h(q) もあいまいです。
コンパイラーは、次の場合に、部分選択を使用します。
関連参照