Oui, à la fois un extern template class
(appelée instanciation explicite déclaration par la norme) et un template class
(appelée instanciation explicite définition par la norme) peuvent se trouver dans la même unité de traduction, si la définition (sans extern
) suit la déclaration (avec extern
):
(§14.7.2/11) Si une entité fait l'objet à la fois d'une déclaration d'instanciation explicite et d'une dénition d'instanciation explicite dans la même unité de traduction, la dénition doit suivre la déclaration. Une entité qui fait l'objet d'une déclaration d'instanciation explicite et qui est également utilisée d'une manière qui causerait autrement une instanciation implicite (14.7.1) dans l'unité de traduction doit faire l'objet d'une dénition d'instanciation explicite quelque part dans le programme ; sinon le programme est mal formé, aucun diagnostic n'est requis. [Note : Cette règle s'applique aux fonctions en ligne même si une déclaration d'instanciation explicite d'une telle entité n'a aucun autre effet normatif. Cette règle est nécessaire pour garantir que si l'adresse d'une fonction inline est prise dans une unité de traduction dans laquelle l'implémentation a choisi de supprimer le corps hors ligne, une autre unité de traduction fournira le corps. - note de fin ] Une déclaration d'instanciation explicite ne doit pas nommer une spécialisation d'un modèle avec un lien interne.
(C'est moi qui souligne). Les termes déclaration d'instanciation explicite y définition explicite de l'instanciation sont définis ici :
(§14.7.2/2) La syntaxe de l'instanciation explicite est :
explicite-instanciation :
extern
opt template
déclaration
Il existe deux formes d'instanciation explicite : une dénition d'instanciation explicite et une déclaration d'instanciation explicite. Une déclaration d'instanciation explicite commence par le mot-clé extern.
En l'effet de ces instanciations explicites est le suivant :
-
La déclaration d'instanciation explicite (avec extern
) empêche toute implicite pour prendre effet (sauf pour les fonctions en ligne et les modèles de classe). spécialisations , §14.7.2/10).
-
La définition explicite de l'instanciation (sans extern
) provoque l'instanciation peu importe ce qui se passe c'est-à-dire qu'elle remplace la déclaration d'instanciation explicite (ceci découle également de la §14.7.2/10).
Commentaires généraux
Le fait que vos déclarations d'instanciation explicites se trouvent dans le fichier d'en-tête qui définit le modèle implique que quelqu'un qui inclut les fichiers d'en-tête afin d'utiliser le modèle devra également ajouter une instanciation explicite. définition ou, alternativement, a besoin d'un lien vers le code d'une autre entreprise. .cpp
qui comprend une telle définition explicite de l'instanciation.
Cela peut prêter à confusion et ce n'est probablement pas une très bonne idée si vous vous attendez à ce que de nombreux utilisateurs différents instancient le modèle pour de nombreux types différents. Mais cela peut être judicieux si le nombre d'instanciations pour des types distincts est faible et que vous pouvez toutes les anticiper. Bien sûr, vous devez vous assurer qu'il existe un (ou plusieurs) .cpp
qui incluent une instanciation explicite. définitions pour toutes les instanciations requises, et que le fichier objet correspondant est lié au projet au moment de la construction.