明示的特殊化 (C++ のみ)

テンプレート引数の特定のセットでテンプレートをインスタンス化する場合、 コンパイラーは、それらのテンプレート引数に基づいて新規の定義を生成します。 この定義生成の振る舞いをオーバーライドできます。 その代わりに、コンパイラーがテンプレート引数の任意のセットで使用する定義を、 指定することができます。 これは、明示的特殊化 と呼ばれます。 次のものを明示的に特殊化できます。
  • 関数またはクラス・テンプレート
  • クラス・テンプレートのメンバー関数
  • クラス・テンプレートの静的データ・メンバー
  • クラス・テンプレートのメンバー・クラス
  • クラス・テンプレートのメンバー関数テンプレート
  • クラス・テンプレートのメンバー・クラス・テンプレート
構文図を読む構文図をスキップする
 明示的特殊化宣言の構文 

>>-template--<-->--declaration_name--+------------------------------+--declaration_body-><
                                     '-<--template_argument_list-->-'                     

template<> 接頭部は、次のテンプレート宣言が、 テンプレート・パラメーターを取得しないということを示しています。 declaration_name は、以前に宣言されたテンプレートの名前です。 少なくとも特殊化が参照されているまでは、明示的特殊化を前もって宣言できること、 その場合 declaration_body は、オプションであることに注意してください。

次の例は、明示的特殊化を示しています。
using namespace std;

template<class T = float, int i = 5> class A
{
   public:
      A();
      int value;
};

template<> class A<> { public: A(); };
template<> class A<double, 10> { public: A(); };

template<class T, int i> A<T, i>::A() : value(i) {
   cout << "Primary template, "
        << "non-type argument is " << value << endl;
}

A<>::A() {
   cout << "Explicit specialization "
        << "default arguments" << endl;
}

A<double, 10>::A() {
   cout << "Explicit specialization "
        << "<double, 10>" << endl;
}

int main() {
   A<int,6> x;
   A<> y;
   A<double, 10> z;
}
上記の例の出力は、以下のとおりです。
Primary template non-type argument is: 6
Explicit specialization default arguments
Explicit specialization <double, 10>

この例では、主テンプレート (特殊化されているテンプレート) クラス A に対して、2 つの明示的特殊化を宣言しました。 オブジェクト x は、主テンプレートのコンストラクターを使用します。 オブジェクト y は、明示的特殊化 A<>::A() を使用します。 オブジェクト z は、明示的特殊化 A<double, 10>::A() を使用します。

C++0x C++0x のみの始まり。

明示的特殊化定義およびインライン・ネーム・スペース定義

インライン・ネーム・スペース定義は、最初に inline キーワードを使用するネーム・スペース定義です。 インライン・ネーム・スペースのメンバーは、エンクロージング・ネーム・スペースのメンバーでもあるかのように、インスタンス生成または特殊化を明示的に実行できます。詳しくは、インライン名前空間定義 (C++11)を参照してください。

C++0x C++0x のみの終わり。