Pourquoi est-ce que je reçois des erreurs de «symbole externe non résolu» lors de l’utilisation de modèles?

Lorsque j’écris du code C ++ pour une classe à l’aide de modèles et que je divise le code entre un fichier source (CPP) et un fichier d’en-tête (H), je reçois beaucoup d’erreurs de “symboles externes non résolus” bien que le fichier object soit correctement construit et inclus dans la liaison. Qu’est-ce qui se passe ici, et comment puis-je le réparer?

Les classes et fonctions basées sur des modèles ne sont pas instanciées tant qu’elles ne sont pas utilisées, généralement dans un fichier .cpp distinct (par exemple, la source du programme). Lorsque le modèle est utilisé, le compilateur a besoin du code complet pour que cette fonction puisse générer la fonction correcte avec le type approprié. Cependant, dans ce cas, le code de cette fonction est détaillé dans le fichier source du modèle et n’est donc pas disponible.

En conséquence, le compilateur suppose simplement qu’il est défini ailleurs et insère uniquement l’appel à la fonction basée sur un modèle. Lorsqu’il s’agit de comstackr le fichier source du modèle, le type de modèle spécifique utilisé dans la source du programme n’est pas utilisé et ne génère donc toujours pas le code requirejs pour la fonction. Cela se traduit par le symbole externe non résolu.

Les solutions disponibles sont les suivantes:

  1. inclure la définition complète de la fonction membre dans le fichier d’en-tête du modèle et ne pas avoir de fichier source pour le modèle,
  2. définir toutes les fonctions membres dans le fichier source du modèle comme “inline”, ou
  3. définir les fonctions membres dans la source du modèle avec le mot clé “export”. Malheureusement, cela n’est pas supporté par beaucoup de compilateurs. (Mise à jour: ceci a été supprimé de la norme à partir de C ++ 11. )

Les deux 1 et 2 abordent essentiellement le problème en donnant au compilateur l’access au code complet pour la fonction basée sur des modèles quand il tente de générer la fonction typée dans la source du programme.

Une autre option consiste à placer le code dans le fichier cpp et, dans le même fichier cpp, à append des instanciations explicites du modèle avec les types que vous prévoyez d’utiliser. Ceci est utile si vous savez que vous ne l’utiliserez que pour quelques types que vous connaissez à l’avance.

Pour chaque fichier contenant le fichier .h, vous devez insérer les deux lignes:

 #include "MyfileWithTemplatesDeclaration.h" #include "MyfileWithTemplatesDefinition.cpp" 

échantillon

 #include "list.h" #include "list.cpp" //<---for to fix bug link err 2019 int main(int argc, _TCHAR* argv[]) { list my_list; my_list.add_end(3); . . } 

aussi, vous n’oubliez pas de placer votre classe de déclaration parmi les constantes de centinels

 #ifndef LIST_H #define LIST_H #include  . . template  class list { private: int m_size, m_count_nodes; T m_line; node *m_head; public: list(void); ~list(void); void add_end(T); void print(); }; #endif