テンプレートの部分特殊化
出典: フリー百科事典『ウィキペディア(Wikipedia)』
テンプレートの部分特殊化 (Partial template specialization)は、汎用的(ジェネリック)なコードをコンパイル時に最適化する手法のことである。しばしばC++で用いられ、クラステンプレートのテンプレート引数をいくつかだけ特殊化することができる機能である。
[編集] テンプレートと特殊化
テンプレートはメタクラスである。つまりコンパイラに対してどのようなクラスを作るかを指示したある種の抽象データ型であると言える。たとえばテンプレートであるvector(動的配列)をプログラマがを使うときには、vector<int>、vector<string>などのようにデータ型を指定して実体化する。実体化されたvectorは、コンパイラの生成したオブジェクトコードの中ではそれぞれ別のコードが生成され、それぞれ別のクラスとして扱われる。
もしテンプレートクラスは特定のデータ型を指定して使われることが多いと知っており、そのデータ型の場合にだけ人の手で最適化をかけられる(たとえば整数型のときは2の乗数での乗除算をシフト演算にするなど)としたら、通常の場合のテンプレートとは別に、特殊化を行うことができる。テンプレートを使用する際に指定されたデータ型が、特殊化されているものだった場合、コンパイラは特殊化されたものをコンパイルしてコードを生成する。
たとえば、これは要素数nの配列の先頭要素を指すポインタpに対して、全ての要素をxにするということを行うC++の関数テンプレートarray_fillである。
template <typename T> inline void array_fill(T* p, std::size_t n, T x) { std::fill_n(p, p + n, x); }
もしその配列がchar型だった場合、標準Cライブラリのmemsetを使うことができ、その方がstd::fill_nより高速化されているとする。そのような場合、次のように特殊化すれば、array_fillにchar型の先頭要素を指すポインタが渡されたときにはmemsetを用いるようにすることができる。
template <> inline void array_fill(char* p, std::size_t n, char x) { std::memset(p, x, n); }
[編集] 部分特殊化
STLのmapのように2つのテンプレート引数をとるクラステンプレートがあったとする。以前は、どちらか一方のみ型を特定して特殊化することができなかった。しかしそれを可能にしたのがテンプレートの部分特殊化である。しかし最近まで部分特殊化に対応しているコンパイラはほとんど存在しなかった上、今もなお対応していないコンパイラも多い。
カテゴリ: 書きかけの節のある項目 | C++ | プログラミング言語の構文