名前空間
変種
操作

テンプレート

提供: cppreference.com
< cpp‎ | language
 
 
C++言語
一般的なトピック
フロー制御
条件付き実行文
繰り返し文 (ループ)
ジャンプ文
関数
関数宣言
ラムダ関数宣言
inline 指定子
例外指定 (非推奨)
noexcept 指定子 (C++11)
例外
名前空間
指定子
decltype (C++11)
auto (C++11)
alignas (C++11)
記憶域期間指定子
初期化
代替表現
リテラル
ブーリアン - 整数 - 浮動小数点
文字 - 文字列 - nullptr (C++11)
ユーザ定義 (C++11)
ユーティリティ
属性 (C++11)
typedef 宣言
型エイリアス宣言 (C++11)
キャスト
暗黙の変換 - 明示的な変換
static_cast - dynamic_cast
const_cast - reinterpret_cast
メモリ確保
クラス
クラス固有の関数特性
特別なメンバ関数
テンプレート
その他
 
 

テンプレートは以下のいずれかを定義する C++ のエンティティです。

テンプレートはひとつ以上のテンプレート引数によってパラメータ化されます。 テンプレート引数には型テンプレート引数、非型テンプレート引数、テンプレートテンプレート引数の3種類があります。

テンプレート実引数が提供されたとき、または、推定されたとき (関数テンプレートおよびクラステンプレート (C++17およびそれ以降)の場合のみ)、それらはテンプレートの特殊化、つまり、特定の型または特定の関数の左辺値を得るために、テンプレート仮引数を置き換えます。 特殊化は明示的に提供することもできます。 完全特殊化は関数テンプレートとクラステンプレートのどちらについても行うことができます。 部分特殊化はクラステンプレートに対してのみ行うことができます。

クラステンプレートの特殊化が完全オブジェクト型を要求する文脈で参照されたとき、または関数テンプレートの特殊化が関数の定義の存在を要求する文脈で参照されたとき、そのテンプレートがすでに明示的に特殊化または実体化されていなければ、そのテンプレートは実体化されます (そのためのコードが実際にコンパイルされます)。 クラステンプレートを実体化しても、そのメンバ関数は、使用されていない限り、実体化されません。 異なる翻訳単位によって生成された同一の実体化は、リンク時にマージされます。

テンプレートの定義は暗黙の実体化の時点で可視でなければなりません。 これがテンプレートライブラリが一般的にすべてのテンプレートの定義をヘッダで提供する理由です (例えば ほとんどの boost ライブラリはヘッダオンリーです)。

[編集] 構文

template < parameter-list > requires-clause(C++20)(オプション) declaration (1)
export template < parameter-list > declaration (2) (C++11以前)
template < parameter-list > concept concept-name = constraint-expression ; (3) (C++20およびそれ以降)
declaration - クラス (構造体および共用体を含む)メンバクラスまたはメンバ列挙型関数またはメンバ関数、名前空間スコープの静的データメンバクラススコープの変数または静的データメンバ (C++14およびそれ以降)またはエイリアステンプレート (C++11およびそれ以降)の宣言。 テンプレートのの特殊化を定義しても構いません。
parameter-list - テンプレート仮引数のコンマ区切りの空でないリスト。 各引数は非型引数型引数テンプレート引数またはそれらのいずれかのパラメータパックのいずれかです。
concept-name
constraint-expression
- 制約とコンセプトを参照してください。 (C++20およびそれ以降)
export はテンプレートをエクスポートされるものとして宣言するオプショナルな修飾子です (クラステンプレートで使用した場合は、そのすべてのメンバも同様にエクスポートされるものとして宣言されます)。 エクスポートされたテンプレートを実体化するファイルは、その定義を含む必要はなく、宣言するだけで十分です。 export の実装は稀であり、詳細は処理系によって異なります。 (C++11以前)

テンプレートの仮引数リストには、そのテンプレートの実引数に対する制約を指定するオプショナルな requires-clause を付けることができます。

(C++20およびそれ以降)

[編集] テンプレート化されたエンティティ

クラステンプレート、関数テンプレート、または変数テンプレートそれ自体と同様に、テンプレート内で定義された様々なエンティティは、別々に実体化できるエンティティであるとみなされることはありません (これには、それらのエンティティのデフォルト引数、例外指定、非静的データメンバの初期化子などが含まれます)。 結果として、これらの非テンプレートエンティティは、テンプレートの実体化に通されます。 依存名が探索され、意味論上の制約がチェックされ、使用されるあらゆるテンプレートがこのエンティティが宣言されたテンプレートの実体化の一部として実体化されます。 テンプレートと共に、そのようなエンティティは「テンプレート化されたエンティティ」(または、文献によっては「テンプロイド」) と呼ばれます。

以下のものはすべて、テンプレート化されたエンティティです。

  • クラステンプレート、関数テンプレート、変数テンプレート
  • テンプレート化されたエンティティのメンバ (クラステンプレートの非テンプレートメンバ関数など)
  • テンプレート化されたエンティティである列挙の列挙子
  • テンプレート化されたエンティティ内部で定義または作成されたあらゆるエンティティ (ローカルクラス、ローカル変数、フレンド関数など)
  • テンプレート化されたエンティティの宣言内に現れるラムダ式のクロージャ型