à l'aide extern modèle (C++11)
Figure 1: les modèles de fonction
TemplHeader.h
template<typename T>
void f();
TemplCpp.cpp
template<typename T>
void f(){
//...
}
//explicit instantation
template void f<T>();
Main.cpp
#include "TemplHeader.h"
extern template void f<T>(); //is this correct?
int main() {
f<char>();
return 0;
}
Est-ce la bonne façon d'utiliser les extern template
, ou dois-je utiliser ce mot-clé uniquement pour les modèles de classe comme dans la Figure 2?
Figure 2: modèles de classe
TemplHeader.h
template<typename T>
class foo {
T f();
};
TemplCpp.cpp
template<typename T>
void foo<T>::f() {
//...
}
//explicit instantation
template class foo<int>;
Main.cpp
#include "TemplHeader.h"
extern template class foo<int>();
int main() {
foo<int> test;
return 0;
}
Je sais qu'il est bon de mettre tout cela dans un fichier d'en-tête, mais si nous instancier les modèles avec les mêmes paramètres dans plusieurs fichiers, puis nous avons eu de multiples mêmes définitions et le compilateur va supprimer tous (sauf un) pour éviter les erreurs. Comment puis-je utiliser extern template
? Pouvons-nous l'utiliser uniquement pour les classes, ou pouvons-nous l'utiliser pour les fonctions de trop?
Aussi, la Figure 1 et la Figure 2 peut être étendu à une solution où les modèles sont dans un seul fichier d'en-tête . Dans ce cas, nous devons utiliser la extern template
mot-clé pour éviter les multiples d'un même instantations. Est-ce que pour des classes ou des fonctions trop?
Pourriez-vous prendre le temps de la phrase (une) question plus clairement? De quoi êtes-vous poster le code? Je ne vois pas une question. Aussi,
extern template class foo<int>();
semble être une erreur.il compile très bien sur mon visual studio 2010, sauf le message d'avertissement:Avertissement 1 avertissement C4231: extension non standard utilisé : 'extern' avant du modèle d'instanciation explicite
la question est très simple: comment et quand utiliser extern modèle de mot-clé? (extern modèle est le C++0x nouvel avenir btw) vous avez dit "Aussi, extern modèle de la classe foo<int>(); ça semble être une erreur." non, ce n'est pas, j'ai de nouveau C++ livre et que l'exemple de mon livre.
visual studio est vraiment stupide.. dans le second, le prototype ne correspond pas à la mise en œuvre, et même si je régler ce problème, il dit "attend unqualified-id' près de
()
sur la extern ligne. à la fois votre livre et visual studio sont mauvais, essayez d'utiliser plus conforme à la norme compilateur comme g++ ou clang et vous verrez le problème.OriginalL'auteur codekiddy | 2011-11-15
Vous devez vous connecter pour publier un commentaire.
Vous ne devez utiliser
extern template
pour forcer le compilateur à pas instancier un modèle lors de la vous savez qu'il sera instancié quelque part d'autre. Il est utilisé pour réduire le temps de compilation et de l'objet de la taille du fichier.Par exemple:
Cela se traduira dans les fichiers d'objet suivants:
Si les deux fichiers sont liés, l'un
void ReallyBigFunction<int>()
seront rejetées, entraînant un gaspillage de temps de compilation et de l'objet de la taille du fichier.De ne pas perdre de temps de compilation et de l'objet de la taille du fichier, il y a un
extern
mot-clé qui fait le compilateur compile pas une fonction de modèle. Vous devez utiliser cette si et seulement si vous savez il est utilisé dans le même binaire ailleurs.Changer
source2.cpp
:Voici les fichiers de l'objet:
Lors de ces deux seront reliés ensemble, le deuxième objet fichier suffit d'utiliser le symbole de l'objet premier de fichier. Pas besoin de jeter et aucune perte de temps de compilation et de l'objet de la taille du fichier.
Cela ne devrait être utilisé au sein d'un projet, comme dans les moments où vous utilisez un modèle comme
vector<int>
plusieurs fois, vous devez utiliserextern
dans un seul fichier source.Ceci s'applique également aux classes et fonctionnent comme un seul et même modèle de fonctions membres.
la meilleure explication de la extern modèles que j'ai lu jusqu'à présent!
"si vous savez que son utilisé dans le même binaire quelque part d'autre.". Qui n'est ni suffisante, ni nécessaire. Votre code est "mal formé, pas de diagnostic nécessaires". Vous n'êtes pas autorisé à s'appuyer sur un accord implicite de l'instanciation d'un autre TU (le compilateur est autorisé pour l'optimiser à l'écart, à l'instar d'une fonction inline). Une instanciation explicite doit être fournie dans un autre TU.
Je tiens à souligner que cette réponse est probablement faux, et je suis mordu par elle. Heureusement, Johannes commentaire avait un certain nombre de voix et j'ai payé plus d'attention à elle, cette fois. Je ne peux que supposer que la grande majorité des électeurs sur cette question n'a pas réellement de mettre en œuvre ces types de modèles dans plusieurs unités de compilation (comme je l'ai fait aujourd'hui)... Au moins pour le bruit, le seul moyen infaillible est de mettre ces modèle définitions dans votre tête! Être averti!
pourriez-vous élaborer un peu plus ou peut-être fournir une meilleure réponse? Je ne suis pas sûr si j'ai complètement compris vos objections.
OriginalL'auteur Dani
Wikipedia a la la meilleure description
Le avertissement:
nonstandard extension used...
Microsoft VC++ utilisé pour avoir un non-standard version de cette fonction depuis quelques années déjà (en C++03). Le compilateur signale que, pour prévenir des problèmes de portabilité avec code à compiler sur différents compilateurs.
Regardez l'exemple dans la page liée de voir que ça fonctionne à peu près de la même façon. Vous pouvez vous attendre le message pour aller avec les futures versions de MSVC, sauf bien sûr lors de l'utilisation de autres non-standard compilateur extensions en même temps.
"... qui indique au compilateur de ne pas instancier le modèle dans cette unité de traduction." Je ne pense pas que cela est vrai. Toute méthode définie dans la définition de la classe compte en ligne, de sorte que si l'implémentation STL utilise inline méthodes pour
std::vector
(assez sûr que tous d'entre eux),extern
n'a aucun effet.Yep, cette réponse est trompeuse. MSFT doc: "Le mot-clé extern dans la spécialisation ne s'applique que pour les fonctions de membres définies à l'extérieur du corps de la classe. Fonctions définies à l'intérieur de la déclaration de classe sont considérés comme des fonctions inline et sont toujours instancié." Toutes les classes de la STL VS (dernière vérification a été 2017) ne disposent que de méthodes inline malheureusement.
Cela vaut pour tous les inline déclarations, peu importe où ils surviennent, toujours @0kcats
La référence à l'Wiki avec std::vector exemple et une référence pour MSVC dans la même réponse fait croire qu'il pourrait y avoir un certain avantage en utilisant extern std::vector, MSVC, alors qu'il n'est pas si loin. Vous ne savez pas si c'est l'exigence de la norme, peut-être que d'autres compilateurs ont le même problème.
OriginalL'auteur sehe
Le problème connu avec les modèles du code des ballonnements, qui est la conséquence de la génération de la définition de la classe dans chaque et chaque module qui appelle la classe template de la spécialisation. Pour éviter cela, à partir de C++0x, on peut utiliser le mot-clé extern en face de la classe de modèle de spécialisation
#include <MyClass>
extern template class CMyClass<int>;
Explicite instantion de la classe de modèle devrait arriver dans une seule unité de traduction, de préférence celui avec la définition de modèle (MyClass.cpp)
OriginalL'auteur damirlj
Si vous avez utilisé extern pour les fonctions avant, exactement de la même philosophie est suivie pour les modèles. si non, va bien extern pour des fonctions simples peut aider. Aussi, vous voudrez peut-être mettre la extern(s) dans le fichier d'en-tête et inclure l'en-tête lorsque vous en avez besoin.
OriginalL'auteur qqqqq