JavaScript is required to for searching.
ナビゲーションリンクをスキップ
印刷ビューの終了
Oracle Solaris Studio 12.3: C++ ユーザーズガイド     Oracle Solaris Studio 12.3 Information Library (日本語)
search filter icon
search icon

ドキュメントの情報

はじめに

パート I C++ コンパイラ

1.  C++ コンパイラの紹介

2.  C++ コンパイラの使用方法

3.  C++ コンパイラオプションの使い方

パート II C++ プログラムの作成

4.  言語拡張

5.  プログラムの編成

6.  テンプレートの作成と使用

7.  テンプレートのコンパイル

7.1 冗長コンパイル

7.2 リポジトリの管理

7.2.1 生成されるインスタンス

7.2.2 全クラスインスタンス化

7.2.3 コンパイル時のインスタンス化

7.2.4 テンプレートインスタンスの配置とリンケージ

7.3 外部インスタンス

7.3.1 キャッシュの衝突の可能性

7.3.2 静的インスタンス

7.3.3 大域インスタンス

7.3.4 明示的インスタンス

7.3.5 半明示的インスタンス

7.4 テンプレートリポジトリ

7.4.1 リポジトリの構造

7.4.2 テンプレートリポジトリへの書き込み

7.4.3 複数のテンプレートリポジトリからの読み取り

7.4.4 テンプレートリポジトリの共有

7.4.5 -instances=extern による テンプレートインスタンスの自動一貫性

7.5 テンプレート定義の検索

7.5.1 ソースファイルの位置規約

7.5.2 定義検索パス

7.5.3 問題がある検索の回避

8.  例外処理

9.  プログラムパフォーマンスの改善

10.  マルチスレッドプログラムの構築

パート III ライブラリ

11.  ライブラリの使用

12.  C++ 標準ライブラリの使用

13.  従来の iostream ライブラリの使用

14.  ライブラリの構築

パート IV 付録

A.  C++ コンパイラオプション

B.  プラグマ

用語集

索引

7.3 外部インスタンス

外部インスタンスの場合では、すべてのインスタンスがテンプレートリポジトリ内に置かれます。テンプレートインスタンスは 1 つしか存在できません。つまり、インスタンスが未定義であるとか、重複して定義されているということはありません。テンプレートは必要な場合にのみ再インスタンス化されます。非デバッグコードの場合、すべてのオブジェクトファイル (テンプレートキャッシュに入っているものを含む) の総サイズは、-instances=extern を指定したときの値が -instances=global を指定したときの値より小さくなることがあります。

テンプレートインスタンスは、リポジトリ内では大域リンケージを受け取ります。インスタンスは、現在のコンパイル単位からは、 外部リンケージで参照されます。


注 - コンパイルとリンクの手順を別々に実行し、コンパイル処理で -instance=extern を指定する場合は、リンク処理でも -instance=extern を指定する必要があります。


この方法には、別のプログラムに変更したり、プログラムを大幅に変更したりした場合にはキャッシュを常にクリアーする必要があるという欠点があります。キャッシュへのアクセスを一度に 1 回だけに限定しなければならないため、キャッシュは、dmake を使用する場合と同じように、並列コンパイルにおけるボトルネックとなります。また、1 つのディレクトリ内に構築できるプログラムは 1 個だけです。

有効なテンプレートインスタンスがキャッシュ内に存在するかどうかを判断することは、単にインスタンスを本体のオブジェクトファイル内に作成してあとで必要に応じてそれを破棄することよりも時間がかかる可能性があります。

外部リンケージは、-instances=extern オプションによって指定します

インスタンスはテンプレートリポジトリ内に保存されているので、外部インスタンスを使用する C++ オブジェクトをプログラムにリンクするには CC コマンドを使用しなければなりません。

使用するすべてのテンプレートインスタンスを含むライブラリを作成する場合には、-xar オプションでコンパイルしてください。ar コマンドは使用できません。例:

example% CC -xar -instances=extern -o libmain.a a.o b.o c.o

7.3.1 キャッシュの衝突の可能性

-instance=extern を指定する場合、キャッシュの衝突の可能性があるため、異なるバージョンのコンパイラを同一ディレクトリ内で実行しないでください。-instances=extern テンプレートモデルでコンパイルする場合は、次の点に注意してください。

7.3.2 静的インスタンス


注 - -instances=globalstatic の利点をすべて提供し、かつ欠点がないので、-instances=static オプションは非推奨です。このオプションは、今はもう存在していない問題を克服するために、以前のバージョンで提供されました。


静的インスタンスの場合は、すべてのインスタンスが現在のコンパイル単位内に置かれます。その結果、テンプレートは各再コンパイル作業中に再インスタンス化されます。インスタンスはテンプレートリポジトリに保存されません。

この方法の欠点は、言語の意味解釈が規定どおりでないこと、かなり大きいオブジェクトと実行可能ファイルが作られることです。

インスタンスは静的リンケージを受け取ります 。これらのインスタンスは、現在のコンパイル単位以外では認識することも使用することもできません。そのため、テンプレートの同じインスタンス化がいくつかのオブジェクトファイルに存在することがあります。複数のインスタンスによって不必要に大きなプログラムが生成されるので、静的インスタンスのリンケージは、テンプレートが重複してインスタンス化される可能性が低い小さなプログラムだけに適しています。

静的インスタンスは潜在的にコンパイル速度が速いため、修正継続機能を使用したデバッグにも適しています。『dbx コマンドによるデバッグ』を参照してください。


注 - プログラムがコンパイル単位間で、テンプレートクラスまたはテンプレート機能の静的データメンバーなどのテンプレートインスタンスの共有に依存している場合は、静的インスタンス方式は使用しないでください。プログラムが正しく動作しなくなります。


静的インスタンスリンケージは、-instances=static コンパイルオプションで指定します。

7.3.3 大域インスタンス

旧リリースのコンパイラとは異なり、新リリースでは、大域インスタンスの複数のコピーを防ぐ必要はありません。

この方法の利点は、ほかのコンパイラで通常受け入れられる正しくないソースコードを、このモードで受け入れられるようになったという点です。特に、テンプレートインスタンスの中からの静的変数への参照は正当なものではありませんが、通常は受け入れられるものです。

この方法の欠点は、テンプレートインスタンスが複数のファイルにコピーされることから、個々のオブジェクトファイルが通常より大きくなる可能性がある点です。デバッグを目的としてオブジェクトファイルの一部を -g オプションを使ってコンパイルし、ほかのオブジェクトファイルを -g オプションなしでコンパイルした場合、プログラムにリンクされるテンプレートインスタンスが、デバッグバージョンと非デバッグバージョンのどちらであるかを予測することは難しくなります。

テンプレートインスタンスは大域リンケージを受け取ります。これらのインスタンスは、現在のコンパイル単位の外でも認識でき、使用できます。

大域インスタンスは、-instances=global オプションで指定します (デフォルト)。

7.3.4 明示的インスタンス

明示的インスタンスの場合、インスタンスは、明示的にインスタンス化されたテンプレートに対してのみ生成されます。暗黙的なインスタンス化は行われません。インスタンスは現在のコンパイル単位に置かれます。

この方法の利点はテンプレートのコンパイル量もオブジェクトのサイズも、ほかのどの方法より小さくて済むことです。

欠点は、すべてのインスタンス化を手動で行う必要がある点です。

テンプレートインスタンスは大域リンケージを受け取ります。これらのインスタンスは、現在のコンパイル単位の外でも認識でき、使用できます。リンカーは、重複しているものを見つけ、破棄します。

明示的リンケージは、-instances=explicit オプションによって指定します。

7.3.5 半明示的インスタンス

半明示的インスタンスの場合、インスタンスは、明示的にインスタンス化されるテンプレートやテンプレート本体の中で暗黙的にインスタンス化されるテンプレートに対してのみ生成されます。明示的に作成されるインスタンスが必要とするインスタンスは自動的に生成されます。main コード行内で行う暗黙的なインスタンス化は不完全になります。インスタンスは現在のコンパイル単位に置かれます。したがって、テンプレートは再コンパイルごとに再インスタンス化されます。インスタンスが大域リンケージを受けることはなく、テンプレートリポジトリには保存されません。

半明示的インスタンスは、-instances=semiexplicit オプションで指定します。