2016-08-05 4 views
6

J'utilise cette classe avec toutes les fonctions membres, à l'exception d'une seule, qui seront utilisées dans un projet avec plusieurs fichiers sources qui seront liés lors de la compilation. Le type de modèle est inconnu et peut prendre à peu près n'importe quel type. Dans ce cas, j'ai deux fichiers source qui utilisent la classe, donc le fichier d'en-tête avec la déclaration de classe et la définition est #include: ed dans les deux fichiers source. Je reçois alors l'erreur "définition multiple" à la déclaration de fonction de membre de non-modèle de la classe. Je suppose que c'est parce qu'il est défini deux fois pendant le processus de liaison puisque les deux fichiers source ont une définition de la fonction de membre non-modèle. Imaginez le scénario non sens ci-dessous:C++ :: #include: fichier d'en-tête de classe de modèle ing dans plusieurs fichiers source?

Remarque: Supposons que tous les fichiers sont protégés et que iostream est #include: ed si nécessaire.

foo.hpp

class foo 
{ 
public: 
    template <typename X> 
    void f(X); 

    void ff(); 
}; 

#include "foo.tpp" 

foo.tpp

template <typename X> 
void foo::f(X val) 
{ 
    cout << val; 
} 

void foo::ff() // multiple definitions 
{ 
    cout << sizeof(*this); 
} 

main2.cpp

#include "foo.hpp" 

main.cpp

#include "foo.hpp" 

int main() 
{ 
    return 0; 
} 

Ajout du mot-clé en ligne à la définition de la fonction semble résoudre cette erreur, mais je ne veux pas l'utiliser parce que j'ai d'autres fonctions non membres modèle souffrant du même problème qui sont beaucoup plus grandes et sont référencées dans plusieurs parties du code. Y a-t-il un moyen de contourner ou de faire ce que j'essaie de faire? Merci d'avance!

+1

Pour ce que ça vaut, toutes les fonctions modèles sont déjà implicitement 'inline', sauf si elles sont complètement spécialisées. –

+0

Ouch. Vraiment digne d'être mentionné! Je garderai ça à l'esprit. Merci beaucoup pour votre contribution. –

+1

De rien. C'est parce que le code basé sur un modèle doit être visible dans toute unité de traduction qui l'utilise, donc le compilateur est capable de créer du code réel, ce qui signifie que le code doit être en ligne pour permettre plusieurs définitions identiques. Cependant, une fonction modèle spécialisée est traitée comme une fonction normale, car elle n'a pas besoin de remplir de paramètres de modèle et peut donc être traitée comme du code réel (ce qui permet de la lier, contrairement aux fonctions non spécialisées)). –

Répondre

6

Créez un troisième fichier, foo.cpp pour les définitions des fonctions non-template qui ne sont pas déclarées comme inline. La classe est non-template, donc vous n'avez pas besoin de définir toutes ses fonctions membres dans l'en-tête, seulement les modèles (ou maybe not).

+1

Des solutions simples se cachent toujours autour du coin et plusieurs fois j'ai tendance à les manquer. Je n'aurais jamais pensé à ça, et cette question m'inquiète depuis une semaine jusqu'à ce que je décide de laisser tomber ma fierté et de demander. Petite solution très intelligente. Je suppose que j'ai plus de compréhension du compilateur à faire. Merci beaucoup! –