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

Un template est une entité C++ qui définit l'un des éléments suivants :

(depuis C++11)
(depuis C++14)
(depuis C++20)

Les modèles sont paramétrés par un ou plusieurs paramètres de modèle , de trois types : paramètres de modèle de type, paramètres de modèle constants et paramètres de modèle de modèle.

Lorsque des arguments de template sont fournis, ou, pour les templates de fonction et de classe (depuis C++17) uniquement, déduits, ils sont substitués aux paramètres du template pour obtenir une spécialisation du template, c'est-à-dire un type spécifique ou une lvalue de fonction spécifique.

Les spécialisations peuvent également être fournies explicitement : les spécialisations complètes sont autorisées pour les modèles de classe , de variable (depuis C++14) et de fonction, les spécialisations partielles sont uniquement autorisées pour les modèles de classe et les modèles de variable (depuis C++14) .

Lorsqu'une spécialisation de classe template est référencée dans un contexte qui nécessite un type d'objet complet, ou lorsqu'une spécialisation de fonction template est référencée dans un contexte qui nécessite l'existence d'une définition de fonction, le template est instancié (le code correspondant est réellement compilé), sauf si le template a déjà été explicitement spécialisé ou explicitement instancié. L'instanciation d'une classe template n'instancie aucune de ses fonctions membres sauf si elles sont également utilisées. Au moment de l'édition des liens, les instanciations identiques générées par différentes unités de traduction sont fusionnées.

La définition d'un modèle de classe doit être visible au point d'instanciation implicite, c'est pourquoi les bibliothèques de modèles fournissent généralement toutes les définitions de modèles dans les en-têtes (par exemple, la plupart des bibliothèques boost sont header-only ).

Table des matières

Syntaxe

template < liste-de-paramètres  > clause-requires  (optionnel) déclaration (1)
export template < liste-de-paramètres  > déclaration (2) (jusqu'en C++11)
template < liste-de-paramètres  > concept nom-concept = expression-contrainte  ; (3) (depuis C++20)
parameter-list - une liste non vide séparée par des virgules des paramètres de template , chacun étant soit un paramètre constant , un paramètre de type , un paramètre de template , ou un pack de paramètres de l'un de ceux-ci (depuis C++11) .
requires-clause - (depuis C++20) une clause requires qui spécifie les contraintes sur les arguments du template.
declaration - déclaration d'une classe (incluant struct et union) , d'une classe membre ou d'un type d'énumération membre , d'une fonction ou fonction membre , d'un membre de données statique au niveau de la portée de l'espace de noms , d'une variable ou d'un membre de données statique au niveau de la portée de la classe (depuis C++14) , ou d'un alias de template (depuis C++11) . Elle peut également définir une spécialisation de template .
concept-name
constraint-expression
- voir contraintes et concepts

export était un modificateur optionnel qui déclarait le modèle comme exporté (lorsqu'il était utilisé avec un modèle de classe, il déclarait également tous ses membres comme exportés). Les fichiers qui instanciaient des modèles exportés n'avaient pas besoin d'inclure leurs définitions : la déclaration était suffisante. Les implémentations de export étaient rares et en désaccord entre elles sur les détails.

(jusqu'à C++11)

Identifiants de template

Un identifiant de template a l'une des syntaxes suivantes :

template-name  < template-argument-list  (optionnel) > (1)
operator op  < template-argument-list  (optionnel) > (2)
operator "" identifier < template-argument-list  (optionnel) > (3) (depuis C++11)
(obsolète)
operator user-defined-string-literal < template-argument-list  (optionnel) > (4) (depuis C++11)
1) Un identifiant de modèle simple .
2) Un identifiant de modèle de fonction d'opérateur.
3,4) Un literal operator identifiant de modèle de fonction.
template-name - un identifiant qui nomme un template
op - un opérateur surchargeable
identifier - un identifiant
user-defined-string-literal - "" suivi d'un identifiant


Un identifiant de modèle simple qui désigne une spécialisation de modèle de classe désigne une classe.

Un identifiant de modèle qui nomme une spécialisation de modèle d'alias désigne un type.

Un identifiant de modèle qui nomme une spécialisation de modèle de fonction nomme une fonction.

Si toutes les conditions suivantes sont satisfaites, un identifiant de template est valide :

  • Il y a au plus autant d'arguments que de paramètres ou un paramètre est un parameter pack (depuis C++11) .
  • Il existe un argument pour chaque paramètre non-déductible non-pack (depuis C++11) qui n'a pas d'argument template par défaut.
  • Chaque argument template correspond au paramètre template correspondant.
  • La substitution de chaque argument template dans les paramètres template suivants (s'il y en a) réussit.
  • Si l'identifiant de template est non-dépendant , les contraintes associées sont satisfaites comme spécifié ci-dessous.
(depuis C++20)

Un identifiant de modèle simple non valide est une erreur de compilation, sauf s'il nomme une spécialisation de fonction modèle (auquel cas SFINAE peut s'appliquer).

template<class T, T::type n = 0>
class X;
struct S
{
    using type = int;
};
using T1 = X<S, int, int>; // erreur : trop d'arguments
using T2 = X<>;            // erreur : pas d'argument par défaut pour le premier paramètre template
using T3 = X<1>;           // erreur : la valeur 1 ne correspond pas au paramètre de type
using T4 = X<int>;         // erreur : échec de substitution pour le second paramètre template
using T5 = X<S>;           // OK

Lorsque le template-name d'un simple template id désigne un modèle non-fonction contraint ou un paramètre de modèle de modèle contraint, mais pas un modèle membre qui est membre d'une spécialisation inconnue, et que tous les arguments de modèle dans le simple template id sont non-dépendants, les contraintes associées du modèle contraint doivent être satisfaites :

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
(depuis C++20)

Si toutes les conditions suivantes sont satisfaites, deux identifiants de template sont same :

  • Leurs template-name s ou opérateurs font référence au même modèle.
  • Leurs arguments de type de modèle correspondants sont du même type.
  • Les valeurs des paramètres de modèle déterminées par leurs arguments de modèle constants correspondants sont template-argument-equivalent .
  • Leurs arguments de modèle de modèle correspondants font référence au même modèle.

Deux identifiants de modèle identiques font référence à la même variable, (depuis C++14) classe ou fonction.

Entité template

Une entité template (ou, dans certaines sources, « temploïde ») est toute entité définie (ou, pour une expression lambda , créée) (depuis C++11) dans une définition de template. Toutes les entités suivantes sont des entités template :

  • une classe/fonction /variable (depuis C++14) template
(depuis C++20)
  • un membre d'une entité template (comme une fonction membre non-template d'une classe template)
  • un énumérateur d'une énumération qui est une entité template
  • toute entité définie ou créée dans une entité template : une classe locale, une variable locale, une fonction amie, etc
  • le type de fermeture d'une expression lambda qui apparaît dans la déclaration d'une entité template
(depuis C++11)

Par exemple, dans

template<typename T>
struct A
{
    void f() {}
};

la fonction A::f n'est pas un modèle de fonction, mais est toujours considérée comme étant template.


Une fonction template est une fonction template ou une fonction qui est template.

Une classe template est un modèle de classe ou une classe qui est template.

Une variable templatée est un modèle de variable ou une variable qui est templatée.

(depuis C++14)

Mots-clés

template , export

Rapports de défauts

Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.

DR Appliqué à Comportement publié Comportement corrigé
CWG 2293 C++98 les règles pour déterminer si un identifiant
de template est valide n'étaient pas fournies
fournies
CWG 2682 C++98
C++14
les définitions de fonction template/classe template
(C++98)/variable template (C++14) manquaient
ajoutées
P2308R1 C++98 deux identifiants de template étaient différents si leurs
arguments de template constants correspondants
n'étaient pas template-argument-équivalents
ils sont différents si leurs valeurs de paramètres
de template constants correspondants
ne sont pas template-argument-équivalentes

Voir aussi

Documentation C pour Sélection générique