Ce problème consiste à définir et à déclarer un modèle de fonction dans un espace de noms défini dans un fichier externe à partir de laquelle la fonction est instanciée. Voici le plus petit exemple reproductible que je pourrais proposer. 4 Fichiers Suivre:
La déclaration de modèle de fonction dans un espace de noms nommé: p> la définition de modèle de fonction dans un fichier séparé: p> L'en-tête du programme principal p> enfin, le programme principal où le modèle de fonction est appelé: p> Je compile comme suit: p> Celles-ci fonctionnent bien. Maintenant, pour la liaison: p> et l'erreur de compilateur résultante sur la référence non définie: p> < PRE> XXX PRE> Il y a un problème évident avec le code qui ne se met pas disponible à partir de l'espace de noms code> ou dans la barre En outre, lorsque j'essaie de placer la définition de Pouvez-vous perdre une erreur à mon compilateur d'erreur de liaison? p> p> g ++ -c -o bar.o bar.cpp code> p>
g ++ -c -o foo. O FOO.CPP CODE> P>
g ++ bar.o foo.o -o foobar code> p>
bar code> de la compilation. p>
dosomething code> dans la barre
bar.h code>, comme je voudrais contourner les problèmes lors de la définition des méthodes de modèle de classe dans Séparez les fichiers .CPP, je reçois la même erreur. P>
4 Réponses :
Mettre en place des définitions de modèles dans un fichier source distincte n'est pas bien supportée (je crois que le seul compilateur qui prend en charge Comeau).
Vous devez déplacer la définition dans vos fichiers d'en-tête: P>
// bar.h namespace barspace { template <typename Iter> void DoSomething (Iter first, Iter last) { typedef typename std::iterator_traits<Iter>::value_type val_t; std::sort (first, last); } } // namespace barspace
Je comprends pourquoi la liaison a besoin de cela, mais cela ne vaingait pas tout le but d'avoir un fichier d'en-tête séparé?
De nombreux compilateurs n'aiment pas que les fonctions de modèle définies dans des fichiers séparés. Placez toute la définition dans le fichier d'en-tête et il devrait compiler simplement bien. P>
Vous essayez de masquer la mise en œuvre de votre fonction modélise dans le fichier CPP, qui, malheureusement, n'est pas possible pour la plupart des compilateurs. Les fonctions / classes modèles sont instanciées lorsqu'elles sont utilisées, donc au point où vous appelez Il y a quelques solutions . P> Déplacez le corps de la fonction dans le fichier d'en-tête. Vous avez eu du mal à le faire avant, mais je dirais que cela est lié à autre chose. C'est l'approche préférée. P> LI>
Inclure le fichier CPP de Instanciez le modèle de DOSOMOD "code>, le compilateur a besoin de la définition de la fonction pour pouvoir le compiler.
foo.cpp code>. (sauvage, mais pas
Double CODE>: P> LI>
OL>
// bar.cpp
#include "bar.h"
namespace barspace {
template<>
void DoSomething<double> (double first, double last) {
typedef typename std::iterator_traits<double>::value_type val_t;
std::sort (first, last);
}
} // namespace barspace
Vous devez définir des fonctions de modèle dans les en-têtes. Vous ne pouvez pas les déclarer, puis les définir dans un fichier de mise en œuvre; cela ne fonctionnera tout simplement pas. La raison est que le compilateur doit instancier em> les modèles avant de pouvoir les appeler. Pour instancier un modèle de fonction, le compilateur a besoin de deux choses: p>
Dans votre cas, le compilateur fonctionne avec deux unités de compilation. Il peut bien les exécuter dans deux processus différents, de sorte que les unités de compilation sont indépendantes les unes des autres. Lorsque le compilateur compile Bar.cpp, il voit une définition de modèle sans demandes (appels) pour des instanciations spécifiques. Par conséquent, le compilateur n'instient pas le gabarit; Compiler Bar.CPP Rendements, en fait, rien. Le compilateur est suffisamment "intelligent" pour voir que vous n'avez pas besoin de ce modèle et l'optimise jusqu'à zéro surcharge. P>
Bien sûr, vous avez besoin de ce modèle - dans FOO.CPP - mais c'est une unité de compilation différente, et maintenant, le compilateur a tout oublié (ou n'a pas encore appris) à propos de Bar.cpp. Le compilateur se trouve toutefois une déclaration de la fonction de modèle et rend l'hypothèse habituelle que si elle a été déclarée, elle a été définie (instanciée) ailleurs - et ne dit rien. P>
Enfin, la liaison vient et obtient la vue ultime des oiseaux. Il peut voir qu'il n'y a pas de Il y a quelques solutions à votre problème. La meilleure solution consiste à utiliser le mot-clé code> exporter code> lorsque vous déclarez le modèle. Malheureusement, c'est aussi la pire solution, puisque la grande majorité des compilateurs ne prennent pas en charge cette fonctionnalité standard. P>
Sérieusement, votre meilleur pari est de définir votre modèle dans le fichier d'en-tête. Ne le déclarez pas là-bas,
Dosomething
std :: vecteur