テンプレート定義を編成するもう 1 つの方法は、テンプレートの定義をテンプレート定義ファイルに記述することです。この例を次に示します。
twice.h
#ifndef TWICE_H #define TWICE_H template <class Number> Number twice(Number original); #endif TWICE_H
twice.cc
template <class Number> Number twice( Number original ) { return original + original; }
main.cc
#include “twice.h” int main( ) { return twice<int>( -3 ); }
テンプレート定義ファイルには、べき等ではないヘッダーファイルをインクルードしてはいけません。また、通常はテンプレート定義ファイルにヘッダーファイルをインクルードする必要はありません。べき等ヘッダーファイルを参照してください。なお、テンプレートの定義分離型編成は、すべてのコンパイラでサポートされているわけではありません。
独立した定義ファイルはヘッダーファイルなので、多数のファイルに暗黙のうちにインクルードされることがあります。そのため、テンプレート定義の一部でないかぎり関数と変数はこのファイルに含めないようにします。独立した定義ファイルには、typedef などの型定義を定義できます。
このように、テンプレート宣言とテンプレート定義を別々のファイルに配置した場合は、定義ファイルの内容、その名前、配置先に特に注意する必要があります。さらに、定義ファイルの配置先をコンパイラに明示的に通知する必要もあります。テンプレート定義の検索規則については、テンプレート定義の検索を参照してください。
-E オプションまたは -P オプションを使用してプリプロセッサ出力を生成する場合、定義分離ファイルの構成では、テンプレート定義を .i ファイルに含めることが許可されません。見つからない定義があるため、.i ファイルのコンパイルに失敗します。テンプレート定義ファイルをテンプレート宣言ヘッダー (次のコード例を参照) に条件付きで含めることで、コマンド行で -template=no%extdef を使用することによりテンプレート定義を使用可能にできます。libCtd ライブラリと STLport ライブラリは、この方法で実装されます。
// templace declaration file template <class T> class foo { ... }; #ifdef _TEMPLATE_NO_EXTDEF #include "foo.cc" //template definition file #endif
ただし、マクロ _TEMPLATE_NO_EXTDEF を自分で定義しないでください。—template=no%extdef オプションなしで定義すると、テンプレート定義ファイルが複数含められるためにコンパイルエラーが発生することがあります。