部分的特殊化

C++クラス・テンプレートをインスタンス化する場合、 コンパイラーは、受け渡したテンプレート引き数に基づいて定義を作成します。 代替として、それらすべてのテンプレート引き数が、明示的特殊化のものと一致する場合、 コンパイラーは、明示的特殊化が定義した定義を使用します。

部分的特殊化 は、明示的特殊化に汎用性を持たせたものです。 明示的特殊化は、テンプレート引き数リストだけを持っています。 部分的特殊化は、テンプレート引き数リストとテンプレート・パラメーター・リストの両方を持っています。 コンパイラーは、テンプレート引き数リストがテンプレートのインスタンス化のテンプレート引き数のサブセットと一致する場合、 部分的特殊化を使用します。 そして、コンパイラーは、テンプレートのインスタンス化の一致しない残りのテンプレート引き数を使用して、 部分的特殊化から新規定義を生成します。

関数テンプレートは、部分的に特殊化することはできません。

構文 - 部分的特殊化
 
>>-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> と一致し、 どれも他よりうまく一致する訳ではないので、この宣言を許可しません。

各クラス・テンプレートの部分的特殊化は、別々のテンプレートです。 クラス・テンプレートの部分的特殊化のメンバーごとに、定義が必要です。

関連参照

IBM Copyright 2003