web-dev-qa-db-fra.com

Pourquoi est-ce que j'obtiens des erreurs "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), j'obtiens un grand nombre d'erreurs de "symbole externe non résolu" lorsqu'il s'agit de lier l'exécutable final, bien que le fichier objet soit correctement construit et inclus dans la liaison. Que se passe-t-il ici et comment puis-je y remédier?

90
dlanod

Les classes et fonctions 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 de cette fonction pour pouvoir créer 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 donc indisponible.

À la suite de tout cela, le compilateur suppose simplement qu'il est défini ailleurs et insère uniquement l'appel à la fonction de modèle. Lorsqu'il s'agit de compiler le fichier source du modèle, le type de modèle spécifique utilisé dans la source du programme n'y est pas utilisé, il ne générera donc toujours pas le code requis pour la fonction. Il en résulte le symbole externe non résolu.

Les solutions disponibles pour cela 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 "en ligne", ou
  3. définir les fonctions membres dans la source du modèle avec le mot clé "export". Malheureusement, cela n'est pas pris en charge par de nombreux compilateurs. (Mise à jour: ceci a été supprimé de la norme depuis C++ 11 .)

Les deux 1 et 2 résolvent le problème en donnant au compilateur l'accès au code complet de la fonction de modèle lorsqu'il tente de créer la fonction typée dans la source du programme.

109
dlanod

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

12
shoosh