Templates
テンプレートは、以下のいずれかを定義するC++エンティティです:
- クラスのファミリー( class template )。これらは nested classes である可能性があります
- 関数のファミリー( function template )。これらは member functions である可能性があります
|
(C++11以降) |
|
(C++14以降) |
|
(C++20以降) |
テンプレートは、1つ以上の template parameters によってパラメータ化されます。これには3種類あります:型テンプレートパラメータ、定数テンプレートパラメータ、およびテンプレートテンプレートパラメータです。
テンプレート引数が提供された場合、または function および class (C++17以降) テンプレートに限り、引数が推論された場合、それらはテンプレートパラメータに代入され、テンプレートの 特殊化 、すなわち特定の型または特定の関数lvalueが得られます。
特殊化は明示的に提供することもできます: 完全特殊化 はクラス 、変数 (C++14以降) および関数テンプレートで許可され、 部分特殊化 はクラステンプレート および変数テンプレート (C++14以降) でのみ許可されます。
クラステンプレートの特殊化が完全なオブジェクト型を必要とする文脈で参照される場合、または関数テンプレートの特殊化が関数定義の存在を必要とする文脈で参照される場合、テンプレートは(明示的に特殊化または明示的にインスタンス化されていない限り) インスタンス化 されます(そのコードが実際にコンパイルされます)。クラステンプレートのインスタンス化は、そのメンバー関数が使用されない限り、いずれのメンバー関数もインスタンス化しません。リンク時には、異なる翻訳単位で生成された同一のインスタンス化がマージされます。
クラステンプレートの定義は暗黙的なインスタンス化の時点で可視でなければなりません。このため、テンプレートライブラリは通常、すべてのテンプレート定義をヘッダー内で提供します(例: ほとんどのBoostライブラリはヘッダーのみ )。
目次 |
構文
template <
parameter-list
>
requires-clause
(オプション)
declaration
|
(1) | ||||||||
export template <
parameter-list
>
declaration
|
(2) | (C++11まで) | |||||||
template <
parameter-list
> concept
concept-name
=
constraint-expression
;
|
(3) | (C++20以降) | |||||||
| parameter-list | - | 空でないカンマ区切りの テンプレートパラメータ のリスト。各パラメータは 定数パラメータ 、 型パラメータ 、 テンプレートパラメータ 、またはこれらのいずれかの パラメータパック (C++11以降) のいずれか。 |
| requires-clause | - | (C++20以降) テンプレート引数に対する 制約 を指定する requires節 。 |
| declaration | - | クラス(構造体および共用体を含む) 、 メンバークラスまたはメンバー列挙型 、 関数 または メンバー関数 、名前空間スコープの静的データメンバー 、クラススコープの変数または静的データメンバー (C++14以降) 、または エイリアステンプレート (C++11以降) の宣言。また、 テンプレート特殊化 を定義することもできる。 |
|
concept-name
constraint-expression |
- | 制約とコンセプト を参照 |
|
export は、テンプレートをエクスポート済みとして宣言するオプションの修飾子でした(クラステンプレートと共に使用された場合、そのすべてのメンバーもエクスポート済みとして宣言されました)。エクスポートされたテンプレートをインスタンス化するファイルは、その定義を含める必要はありませんでした:宣言だけで十分でした。 export の実装は稀であり、詳細について互いに合意がありませんでした。 |
(C++11まで) |
|
このセクションは不完全です
理由:コア構文、テンプレートパラメータ、インスタンス化、class_templateとfunction_templateで共通する内容を統合 |
(注:指定されたテキストブロック内に翻訳対象となる可読テキストが存在しないため、HTML構造はそのまま保持されています)
テンプレート識別子
テンプレート識別子は以下の構文のいずれかを持ちます:
template-name
<
template-argument-list
(オプション)
>
|
(1) | ||||||||
operator
op
<
template-argument-list
(オプション)
>
|
(2) | ||||||||
operator ""
identifier
<
template-argument-list
(オプション)
>
|
(3) |
(C++11以降)
(非推奨) |
|||||||
operator
user-defined-string-literal
<
template-argument-list
(オプション)
>
|
(4) | (C++11以降) | |||||||
| template-name | - | テンプレートを名前付けする 識別子 |
| op | - | オーバーロード可能な演算子 |
| identifier | - | 識別子 |
| user-defined-string-literal | - | "" に続く識別子 |
クラステンプレートの特殊化を指定する単純なテンプレート識別子は、クラスを指定します。
エイリアステンプレートの特殊化を指定するテンプレート識別子は型を表します。
関数テンプレートの特殊化を指定するテンプレート識別子は、関数を指定します。
以下の条件がすべて満たされる場合、テンプレート識別子は valid となります:
- 引数の数はパラメータの数以下である またはパラメータがテンプレート parameter pack である (C++11以降) 。
- デフォルトテンプレート引数を持たない非推論可能な 非pack (C++11以降) パラメータそれぞれに対して引数が存在する。
- 各テンプレート引数は対応するテンプレートパラメータと一致する。
- 各テンプレート引数の後続のテンプレートパラメータ(存在する場合)への代入が成功する。
|
(C++20以降) |
無効な単純テンプレートIDはコンパイル時エラーとなります。ただし、関数テンプレートの特殊化を指す場合(その場合は SFINAE が適用される可能性があります)を除きます。
template<class T, T::type n = 0> class X; struct S { using type = int; }; using T1 = X<S, int, int>; // エラー: 引数が多すぎます using T2 = X<>; // エラー: 最初のテンプレートパラメータにデフォルト引数がありません using T3 = X<1>; // エラー: 値1が型パラメータと一致しません using T4 = X<int>; // エラー: 2番目のテンプレートパラメータの置換に失敗しました using T5 = X<S>; // OK
|
単純テンプレートIDの template-name が、制約付き非関数テンプレート、または制約付きテンプレートテンプレートパラメータを指し、未知の特殊化のメンバであるメンバテンプレートではない場合、かつ単純テンプレートID内の全てのテンプレート引数が非依存である場合、制約付きテンプレートの関連制約は満たされなければならない: template<typename T> concept C1 = sizeof(T) != sizeof(int); template<C1 T> struct S1 {}; template<C1 T> using Ptr = T*; S1<int>* p; // error: constraints not satisfied Ptr<int> p; // error: constraints not satisfied template<typename T> struct S2 { Ptr<int> x; }; // error, no diagnostic required template<typename T> struct S3 { Ptr<T> x; }; // OK, satisfaction is not required S3<int> x; // error: constraints not satisfied template<template<C1 T> class X> struct S4 { X<int> x; // error, no diagnostic required }; template<typename T> concept C2 = sizeof(T) == 1; template<C2 T> struct S {}; template struct S<char[2]>; // error: constraints not satisfied template<> struct S<char[2]> {}; // error: constraints not satisfied |
(C++20以降) |
以下のすべての条件が満たされる場合、2つのテンプレート識別子は same となります:
- それらの template-name または演算子が同じテンプレートを参照している。
- 対応する型テンプレート引数が同じ型である。
- 対応する定数テンプレート引数によって決定されるテンプレートパラメータ値が template-argument-equivalent である。
- 対応するテンプレートテンプレート引数が同じテンプレートを参照している。
同じテンプレート識別子は、同じ 変数、 (C++14以降) クラス、または関数を参照します。
テンプレート化されたエンティティ
テンプレート化されたエンティティ (templated entity) (または一部の資料では「テンプロイド」)は、テンプレート定義内で定義された (または lambda expression の場合、生成された) (C++11以降) あらゆるエンティティを指します。以下のすべてはテンプレート化されたエンティティです:
- a class/function /variable (C++14以降) template
|
(C++20以降) |
- テンプレート化されたエンティティのメンバー(クラステンプレートの非テンプレートメンバー関数など)
- テンプレート化されたエンティティである列挙型の列挙子
- テンプレート化されたエンティティ内で定義または作成される任意のエンティティ:ローカルクラス、ローカル変数、フレンド関数など
|
(C++11以降) |
例えば、
template<typename T> struct A { void f() {} };
関数
A::f
は関数テンプレートではありませんが、依然としてテンプレート化されていると見なされます。
テンプレート化された関数は、関数テンプレートまたはテンプレート化された関数です。
テンプレート化されたクラスは、クラステンプレートまたはテンプレート化されたクラスです。
|
テンプレート化された変数 は、変数テンプレートまたはテンプレート化された変数です。 |
(C++14以降) |
キーワード
不具合報告
以下の動作変更の欠陥報告書は、以前に公開されたC++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| CWG 2293 | C++98 |
テンプレート識別子が有効かどうかを決定する
ルールが提供されていなかった |
提供された |
| CWG 2682 |
C++98
C++14 |
テンプレート化された関数/テンプレートクラス
(C++98)/テンプレート化された変数 (C++14) の 定義が欠落していた |
追加された |
| P2308R1 | C++98 |
対応する定数テンプレート引数が
template-argument-equivalent でない場合、 2つのテンプレート識別子は異なるとされていた |
対応する定数テンプレートパラメータ値が
template-argument-equivalent でない場合、 それらは異なるとされる |
関連項目
|
C documentation
for
Generic selection
|