必要なときだけテンプレートインスタンスがコンパイルされるよう、コンパイルからコンパイルまでのテンプレートインスタンスが テンプレートリポジトリに保存されます。テンプレートリポジトリには、外部インスタンスメソッドを使用するときにテンプレートのインスタンス化に必要となる非ソースファイルがすべて入っています。このリポジトリがほかの種類のインスタンスに使用されることはありません。
テンプレートリポジトリは、デフォルトで、キャッシュディレクトリ (SunWS_cache) にあります。
キャッシュディレクトリは、オブジェクトファイルが置かれるのと同じディレクトリ内にあります。SUNWS_CACHE_NAME 環境変数を設定すれば、キャッシュディレクトリ名を変更できます。SUNWS_CACHE_NAME 変数の値は必ずディレクトリ名にし、パス名にしてはならない点に注意してください。これは、コンパイラが、テンプレートキャッシュディレクトリをオブジェクトファイルディレクトリの下に自動的に入れることから、コンパイラがすでにパスを持っているためです。
コンパイラは、テンプレートインスタンスを格納しなければならないとき、出力ファイルに対応するテンプレートリポジトリにそれらを保存します。たとえば、次のコマンド行では、オブジェクトファイルを ./sub/a.o に、テンプレートインスタンスを ./sub/SunWS_cache 内のリポジトリにそれぞれ書き込みます。コンパイラがテンプレートをインスタンス化するときにこのキャッシュディレクトリが存在しない場合は、このディレクトリが作成されます。
example% CC -o sub/a.o a.cc |
コンパイラは、読み込むオブジェクトファイルに対応するテンプレートリポジトリからテンプレートインスタンスを読み取ります。つまり、次のコマンド行は、/sub1/SunWS_cache と /sub2/SunWS_cache を読み取り、必要な場合は ./SunWS_cache に書き込みます。
example% CC sub1/a.o sub2/b.o |
リポジトリ内にあるテンプレートは、ISO/ANSI C++ 標準の単一定義規則に違反してはいけません。つまり、テンプレートは、どの用途に使用される場合でも、1 つのソースから派生したものでなければなりません。この規則に違反した場合の動作は定義されていません。
この規則に違反しないようにするための、もっとも保守的で、もっとも簡単な方法は、1 つのディレクトリ内では 1 つのプログラムまたはライブラリしか作成しないことです。無関係な 2 つのプログラムが同じ型名または外部名を使用して別のものを意味する場合があります。これらのプログラムがテンプレートリポジトリを共有すると、テンプレートの定義が競合し、予期せぬ結果が生じる可能性があります。
-instances=extern を指定すると、テンプレートリポジトリマネージャーは、リポジトリ中のインスタンスの状態をソースファイルと確実に一致させて最新の状態にします。
たとえば、ソースファイルが -g オプション (デバッグ付き) でコンパイルされる場合には、データベースの中の必要なファイルも -g でコンパイルされます。
さらに、テンプレートリポジトリはコンパイル時の変更を追跡します。たとえば、-DDEBUG フラグ を指定して名前 DEBUG を定義すると、データベースがこれを追跡します。その次のコンパイルでこのフラグを省くと、コンパイラはこの依存性が設定されているテンプレートを再度インスタンス化します。
テンプレートのソースコードを削除する場合や、テンプレートの使用を停止する場合も、テンプレートのインスタンスはキャッシュ内にとどまります。関数テンプレートの署名を変更する場合も、古い署名を使用しているインスタンスはキャッシュ内にとどまります。これらの課題が原因でコンパイル時またはリンク時に予期しない動作が発生した場合は、テンプレートキャッシュをクリアし、プログラムを再構築してください。