インスタンス化された各クラス・テンプレート特殊化は、静的メンバーの専用コピーを所有します。
静的メンバーを明示的に特殊化できます。
次の例は、このことを示しています。
template<class T> class X { public: static T v; static void f(T); }; template<class T> T X<T>::v = 0; template<class T> void X<T>::f(T arg) { v = arg; } template<> char* X<char*>::v = "Hello"; template<> void X<float>::f(float arg) { v = arg * 2; } int main() { X<char*> a, b; X<float> c; c.f(10); }
このコードは、テンプレート引き数 char* がストリング "Hello" を指すようにする、 静的データ・メンバー X::v の初期化を明示的に特殊化します。 関数 X::f() は、テンプレート引き数 float に対して明示的に特殊化されます。 オブジェクト a および b の静的データ・メンバー v は、 同じストリング、つまり "Hello" を指します。 c.v の値は、関数呼び出し c.f(10) の後で 20 になります。
メンバー・テンプレートを、複数の囲みクラス・テンプレート内でネストできます。 いくつかの囲みクラス・テンプレート内でネストされたテンプレートを明示的に特殊化する場合、 特殊化するすべての囲みクラス・テンプレートに、 その宣言の前に template<> を付ける必要があります。 特殊化されていない囲みクラス・テンプレートも残すことはできますが、 その囲みクラス・テンプレートを明示的に特殊化しない限り、 ネスト・クラス・テンプレートを明示的に特殊化できません。 次の例は、ネストされたメンバー・テンプレートの明示的特殊化を示しています。
#include <iostream> using namespace std; template<class T> class X { public: template<class U> class Y { public: template<class V> void f(U,V); void g(U); }; }; template<class T> template<class U> template<class V> void X<T>::Y<U>::f(U, V) { cout << "Template 1" << endl; } template<class T> template<class U> void X<T>::Y<U>::g(U) { cout << "Template 2" << endl; } template<> template<> void X<int>::Y<int>::g(int) { cout << "Template 3" << endl; } template<> template<> template<class V> void X<int>::Y<int>::f(int, V) { cout << "Template 4" << endl; } template<> template<> template<> void X<int>::Y<int>::f<int>(int, int) { cout << "Template 5" << endl; } // template<> template<class U> template<class V> // void X<char>::Y<U>::f(U, V) { cout << "Template 6" << endl; } // template<class T> template<> // void X<T>::Y<float>::g(float) { cout << "Template 7" << endl; } int main() { X<int>::Y<int> a; X<char>::Y<char> b; a.f(1, 2); a.f(3, 'x'); a.g(3); b.f('x', 'y'); b.g('z'); }
下記は、上記のプログラムの出力です。
Template 5 Template 4 Template 3 Template 1 Template 2
フレンド宣言は、明示的特殊化を宣言できません。
関連参照