クラス・テンプレートをインスタンス化する場合、
コンパイラーは、受け渡したテンプレート引き数に基づいて定義を作成します。
代替として、それらすべてのテンプレート引き数が、明示的特殊化のものと一致する場合、
コンパイラーは、明示的特殊化が定義した定義を使用します。
部分的特殊化 は、明示的特殊化に汎用性を持たせたものです。 明示的特殊化は、テンプレート引き数リストだけを持っています。 部分的特殊化は、テンプレート引き数リストとテンプレート・パラメーター・リストの両方を持っています。 コンパイラーは、テンプレート引き数リストがテンプレートのインスタンス化のテンプレート引き数のサブセットと一致する場合、 部分的特殊化を使用します。 そして、コンパイラーは、テンプレートのインスタンス化の一致しない残りのテンプレート引き数を使用して、 部分的特殊化から新規定義を生成します。
関数テンプレートは、部分的に特殊化することはできません。
構文 - 部分的特殊化 >>-template--<template_parameter_list>--declaration_name--------> >--<template_argument_list>--declaration_body------------------><
declaration_name は、以前宣言されたテンプレートの名前です。 declaration_body はオプションなので、 部分的特殊化を前持って宣言できることに注意してください。
以下は、部分的特殊化の使用法を示したものです。
#include <iostream> using namespace std; template<class T, class U, int I> struct X { void f() { cout << "Primary template" << endl; } }; template<class T, int I> struct X<T, T*, I> { void f() { cout << "Partial specialization 1" << endl; } }; template<class T, class U, int I> struct X<T*, U, I> { void f() { cout << "Partial specialization 2" << endl; } }; template<class T> struct X<int, T*, 10> { void f() { cout << "Partial specialization 3" << endl; } }; template<class T, class U, int I> struct X<T, U*, I> { void f() { cout << "Partial specialization 4" << endl; } }; int main() { X<int, int, 10> a; X<int, int*, 5> b; X<int*, float, 10> c; X<int, char*, 10> d; X<float, int*, 10> e; // X<int, int*, 10> f; a.f(); b.f(); c.f(); d.f(); e.f(); }
次に、上記の例の出力を示します。
Primary template Partial specialization 1 Partial specialization 2 Partial specialization 3 Partial specialization 4
コンパイラーは、宣言 X<int, int*, 10> f が、 template struct X<T, T*, I>、template struct X<int, T*, 10>、 または template struct X<T, U*, I> と一致し、 どれも他よりうまく一致する訳ではないので、この宣言を許可しません。
各クラス・テンプレートの部分的特殊化は、別々のテンプレートです。 クラス・テンプレートの部分的特殊化のメンバーごとに、定義が必要です。
関連参照