43 votes

Erreur de référence non définie pour la méthode du modèle

Cela a été me rend fou de la dernière heure et demi. Je sais que c'est une petite chose, mais impossible de trouver quel est le problème (le fait que c'est une saison des pluies de vendredi après-midi, bien sûr, n'aide pas).

J'ai défini la classe suivante qui va contenir les paramètres de configuration de lire un fichier et me permettra d'y accéder à partir de mon programme:

class VAConfig {
    friend std::ostream& operator<<( std::ostream& lhs, const VAConfig& rhs);

private:
    VAConfig();
    static std::string      configFilename;
    static VAConfig*        pConfigInstance;
    static TiXmlDocument*   pXmlDoc;
    std::map<std::string, std::string> valueHash;

public:
    static VAConfig* getInstance();
    static void setConfigFileName( std::string& filename ) { configFilename = filename; }
    virtual ~VAConfig();

    void readParameterSet( std::string parameterGroupName );
    template<typename T> T readParameter( const std::string parameterName );
    template<typename T> T convert( const std::string& value );
};

où la méthode convert() est définie en VAConfig.cpp comme

template <typename T>
T VAConfig::convert( const std::string& value )
{
    T t;
    std::istringstream iss( value, std::istringstream::in );
    iss >> t;
    return t;
}

Tout à fait simple. Mais quand je test à partir de mon programme principal à l'aide de

int y = parameters->convert<int>("5");

Je reçois un undefined reference to 'int VAConfig::convert<int>...' d'erreur de compilation. Idem pour readParameter().

Regardé beaucoup de modèle de tutoriels mais coul pas à comprendre cela. Des idées?

69voto

Seth Johnson Points 6471

Basé sur un modèle de code de mise en œuvre ne devrait jamais être dans un .cpp le fichier: votre compilateur a à voir en même temps qu'il voit le code qui l'appelle (sauf si vous utilisez instanciation explicite pour générer le basé sur un modèle de code objet, mais même alors, .cpp est le mauvais type de fichier à utiliser).

Ce que vous devez faire est de déplacer la mise en œuvre de l'en-tête de fichier, ou un fichier tel qu' VAConfig.t.hpp, puis #include "VAConfig.t.hpp" chaque fois que vous utilisez l'un basé sur un modèle de fonctions membres.

10voto

dma Points 1190

Si vous déplacez l'implémentation des méthodes basées sur des modèles (convert et readParameter) vers le fichier d'en-tête, cela devrait fonctionner.

Le compilateur doit avoir accès aux implémentations des fonctions modèles aux points où elles sont instanciées.

5voto

xtofl Points 22333

Un modèle de méthode est simplement un ... modèle de méthode. Les arguments de modèle sont à pourvoir dans les cas où la méthode est "instancié".

Il devrait être possible de construire un compilateur qui est du contenu de la déclaration d'une méthode de modèle, et un "modèle de compilation' étape de compiler toutes les instances de la méthode de modèle.

Ce n'est pas le cas pour microsoft vc. J'ai entendu un collègue mutter sujet d'être le cas sur unix, bien que.

La plupart des compilateurs instancier le modèle de la méthode sur demande, lorsqu'ils sont utilisés dans le code source. Afin d'instancier la méthode, le compilateur doit "voir" le modèle de corps de la fonction. C'est pourquoi le corps est le plus souvent placé dans le fichier d'en-tête, ou, par exemple .h.cpp fichier qui est ensuite inclus en tant que dernière ligne de la .h fichier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X