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