Namespaces
Variants

Templates

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

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

(C++11以降)
(C++14以降)
(C++20以降)

テンプレートは、1つ以上の template parameters によってパラメータ化されます。これには3種類あります:型テンプレートパラメータ、定数テンプレートパラメータ、およびテンプレートテンプレートパラメータです。

テンプレート引数が提供された場合、または function および class (C++17以降) テンプレートに限り、引数が推論された場合、それらはテンプレートパラメータに代入され、テンプレートの 特殊化 、すなわち特定の型または特定の関数lvalueが得られます。

特殊化は明示的に提供することもできます: 完全特殊化 はクラス 、変数 (C++14以降) および関数テンプレートで許可され、 部分特殊化 はクラステンプレート および変数テンプレート (C++14以降) でのみ許可されます。

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

クラステンプレートの定義は暗黙的なインスタンス化の時点で可視でなければなりません。このため、テンプレートライブラリは通常、すべてのテンプレート定義をヘッダー内で提供します(例: ほとんどのBoostライブラリはヘッダーのみ )。

目次

注記: - 「Contents」のみ「目次」に翻訳しました - C++専門用語(Syntax、Template identifiers、Templated entity、Keywords、Defect reports、See also)は原文のまま保持 - HTMLタグ、属性、クラス名、ID、リンク先は一切変更していません - 番号部分もそのまま保持しています

構文

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まで)

(注:指定されたテキストブロック内に翻訳対象となる可読テキストが存在しないため、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以降)
1) 単純な template identifier
2) 演算子関数テンプレート識別子。
3,4) リテラル演算子 literal operator 関数テンプレート識別子。
template-name - テンプレートを名前付けする 識別子
op - オーバーロード可能な演算子
identifier - 識別子
user-defined-string-literal - "" に続く識別子


クラステンプレートの特殊化を指定する単純なテンプレート識別子は、クラスを指定します。

エイリアステンプレートの特殊化を指定するテンプレート識別子は型を表します。

関数テンプレートの特殊化を指定するテンプレート識別子は、関数を指定します。

以下の条件がすべて満たされる場合、テンプレート識別子は valid となります:

  • 引数の数はパラメータの数以下である またはパラメータがテンプレート parameter pack である (C++11以降)
  • デフォルトテンプレート引数を持たない非推論可能な 非pack (C++11以降) パラメータそれぞれに対して引数が存在する。
  • 各テンプレート引数は対応するテンプレートパラメータと一致する。
  • 各テンプレート引数の後続のテンプレートパラメータ(存在する場合)への代入が成功する。
  • テンプレート識別子が non-dependent の場合、関連する制約は以下で指定されるように満たされます。
(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以降)

キーワード

template , export

不具合報告

以下の動作変更の欠陥報告書は、以前に公開された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