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.  プログラムの編成

5.1 ヘッダーファイル

5.1.1 言語に対応したヘッダーファイル

5.1.2 べき等ヘッダーファイル

5.2 テンプレート定義

5.2.1 テンプレート定義の取り込み

5.2.2 テンプレート定義の分離

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

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

8.  例外処理

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

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

パート III ライブラリ

11.  ライブラリの使用

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

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

14.  ライブラリの構築

パート IV 付録

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

B.  プラグマ

用語集

索引

5.2 テンプレート定義

テンプレート定義は 2 通りの方法で編成することができます。すなわち、テンプレート定義を取り込む方法 (定義取り込み型編成) と、分離する方法 (定義分離型編成) があります。テンプレート定義を取り込んだほうが、テンプレートのコンパイルを制御しやすくなります。

5.2.1 テンプレート定義の取り込み

テンプレートの宣言と定義を、そのテンプレートを使用するファイルの中に含める場合、編成が定義の取り込みです。例:

main.cc

template <class Number> Number twice(Number original);
template <class Number> Number twice(Number original )
    { return original + original; }
int main()
    { return twice<int>(-3); }

テンプレートを使用するファイルに、テンプレートの宣言と定義の両方を含んだファイルをインクルードした場合も、定義取り込み型編成を使用したことになります。例:

twice.h

#ifndef TWICE_H
#define TWICE_H
template <class Number>
Number twice(Number original);
template <class Number> Number twice( Number original )
    { return original + original; }
#endif

main.cc

#include “twice.h”
int main()
    { return twice(-3); }

注 - テンプレートヘッダーをべき等にすることは非常に重要です。「5.1.2 べき等ヘッダーファイル」を参照してください。


5.2.2 テンプレート定義の分離

テンプレート定義を編成するもう一つの方法は、テンプレートの定義をテンプレート定義ファイルに記述することです。この例を次に示します。

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 ); }

テンプレート定義ファイルには、べき等ではないヘッダーファイルをインクルードしてはいけません。また、通常はテンプレート定義ファイルにヘッダーファイルをインクルードする必要はありません。「5.1.2 べき等ヘッダーファイル」を参照してください。なお、テンプレートの定義分離型編成は、すべてのコンパイラでサポートされているわけではありません。

独立した定義ファイルはヘッダーファイルなので、多数のファイルに暗黙のうちにインクルードされることがあります。そのため、テンプレート定義の一部でないかぎり関数と変数はこのファイルに含めないようにします。独立した定義ファイルには、typedef などの型定義を定義できます。


注 - 通常、テンプレート定義ファイルには、ソースファイルの拡張子 (.c.C.cc.cpp.cxx.c++ のいずれか) を付けますが、このテンプレート定義ファイルはヘッダーファイルです。コンパイラは、これらのファイルを必要に応じて自動的に取り込みます。テンプレート定義ファイルの単独コンパイルは行わないでください。


このように、テンプレート宣言とテンプレート定義を別々のファイルに配置した場合は、定義ファイルの内容、その名前、配置先に特に注意する必要があります。さらに、定義ファイルの配置先をコンパイラに明示的に通知する必要もあります。テンプレート定義の検索規則については、「7.5 テンプレート定義の検索」を参照してください。

-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 オプションなしで定義すると、テンプレート定義ファイルが複数含められるためにコンパイルエラーが発生することがあります。