Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Template]Expected constructor.../Undefined reference

    23 juin 2008 à 17:26:55

    Bonjour a Tous.

    J'essaie de coder un template "Vecteur" permettant de creer un vecteur de trois coordonées et donc l'idée est de pouvoir l'utiliser avec different type T.

    La compilation se passait plutot bien,mais des que j'ai essayé d'utiliser "Vecteur", j'ai eu des erreurs de ce type :

    undefined reference to `Vecteur<double>::Vecteur()'

    En fouillant pas mal , je suis tombé sur un topic (pas d'ici) disant que on ne devait pas faire de .h et de .cpp pour un template, mais que tout le code devait se trouver dans le .h ( ce qui m'as choqué...guide de style tout ça...)

    Bon j'essaye alors, et etant malin ( et modeste :p ) j'ai fait un include de vecteur.cpp dans mon vecteur.h ce qui revient a copier le code.

    et dans ce cas, a chacune de mes signature de methodes , dans la partie implemantation (le cpp quoi) j'ai eu :

    expected initializer before «<» token

    expected constructor, destructor, or type conversion before «<» token


    conclusion je desepere (une journée dessus pour l'instant) et je me dit que je vais me faire une petite classe propete de vecteur de double directement, l'idée Template n'etant que du raffinement ( ba oui on manipule que des double..)

    voila le code.cpp(certaines methode ne sont pas(encore) implementés...:

    #include "include/Vecteur.h"
    
    
    
    template < typename T >  Vecteur< T>::Vecteur(const Vecteur < T > &v) : coord(v.coord)
    {
    }
    
    template < typename T >  Vecteur < T>::Vecteur() 
     {
    coord[0]=0;
    coord[1]=0;
    coord[2]=0;
     }
    
    template < typename T >  Vecteur < T>::Vecteur(const  T x, const  T y, const  T z) 
     {
    coord[0]=x;
    coord[1]=y;
    coord[2]=z;
     }
    
    template < typename T > 
    void Vecteur < T >:: Zero()
    {
    	return Vecteur(0,0,0);
    }
    
    template < typename T >
     T Vecteur < T>::PScal(const Vecteur <  T > &t) const
    {
    	return coord[0]*t.coord[0]+ coord[1]*t.coord[1]+coord[2]*t.coord[2];
    }
    
    template < typename T > 
     T Vecteur < T>::Norme() const
    {
    	return PScal(this);
    }
    
    template <typename T >Vecteur< T> Vecteur < T>::PVect(const Vecteur < T > &v1) const
    {
    	return Vecteur(v1.coord[1]*coord[2]-v1.coord[2]*coord[1],
    			v1.coord[2]*coord[0]-v1.coord[0]*coord[2],
    			v1.coord[0]*coord[1]-v1.coord[1]*coord[0]);
    }
    
    template < typename T > Vecteur< T> Vecteur < T>::Diff(const Vecteur < T > &v) const
    {
    	return Vecteur(coord[0]-v.coord[0],coord[1]-v.coord[1],coord[2]-v.coord[2]);
    }
    
    
    template < typename T > void Vecteur< T>::On(const int position,  T valeur)
    {
    	coord[position]=valeur;
    }
    
    template <typename T >  T Vecteur < T>::At(const int position) const
    {
    	return coord[position];
    }
    


    puis le .h
    #ifndef VECTEUR_H
    #define VECTEUR_H
    using namespace std;
    #include <vector>
    #include "../Vecteur.cpp"//cette ligne la est "optionelle", les permieres erreur : compilation sans la ligne, deuxieme erreur: compilation avec la ligne
    
    
    
     template < class T > class Vecteur {
    
    	public:
    	T PScal(const Vecteur < T > &t) const; 
    	T Norme() const;
    	Vecteur < T > PVect(const Vecteur < T > &v1) const;
    	Vecteur < T > Diff(const Vecteur <T > &v) const;
    	T At(const int position) const;
    	void On(const int position, T valeur);
    	
    	//Vecteur(); pas besoin si on utilise la structure vector pour les coord.
    	Vecteur(const Vecteur < T > &v);
    	Vecteur();
    	Vecteur(const T x, const T y, const T z);
    	void Zero();
    	//virtual ~Vecteur(); rien à faire si vector pour les coord
    	
    	private:
    		vector<T> coord;
    };
    #endif//vecteur
    


    les erreurs premieres version (sans l'include moche):
    Element.i686-pc-linux-gnu..o: In function `Element::Element(Vecteur<double>, Vecteur<double>)':
    Element.cpp:(.text+0x338): undefined reference to `Vecteur<double>::Vecteur()'
    Element.cpp:(.text+0x346): undefined reference to `Vecteur<double>::Vecteur()'
    Element.i686-pc-linux-gnu..o: In function `Element::Element(Vecteur<double>, Vecteur<double>)':
    Element.cpp:(.text+0x3d4): undefined reference to `Vecteur<double>::Vecteur()'
    Element.cpp:(.text+0x3e2): undefined reference to `Vecteur<double>::Vecteur()'
    Face.i686-pc-linux-gnu..o: In function `Face::Face(int, int, Vecteur<double>, Vecteur<double>, std::vector<Vecteur<double>, std::allocator<Vecteur<double> > >, ShemaConv)':
    Face.cpp:(.text+0x25d): undefined reference to `Vecteur<double>::Vecteur()'
    Face.i686-pc-linux-gnu..o:Face.cpp:(.text+0x26b): more undefined references to `Vecteur<double>::Vecteur()' follow
    Face.i686-pc-linux-gnu..o: In function `Face::Face(int, int, Vecteur<double>, Vecteur<double>, std::vector<Vecteur<double>, std::allocator<Vecteur<double> > >, ShemaConv)':
    Face.cpp:(.text+0x290): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x2a6): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x2c3): undefined reference to `Vecteur<double>::On(int, double)'
    Face.cpp:(.text+0x2d6): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x2ec): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x309): undefined reference to `Vecteur<double>::On(int, double)'
    Face.cpp:(.text+0x31c): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x332): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x34f): undefined reference to `Vecteur<double>::On(int, double)'
    Face.i686-pc-linux-gnu..o: In function `Face::Face(int, int, Vecteur<double>, Vecteur<double>, std::vector<Vecteur<double>, std::allocator<Vecteur<double> > >, ShemaConv)':
    Face.cpp:(.text+0x3b1): undefined reference to `Vecteur<double>::Vecteur()'
    Face.cpp:(.text+0x3bf): undefined reference to `Vecteur<double>::Vecteur()'
    Face.cpp:(.text+0x3e4): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x3fa): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x417): undefined reference to `Vecteur<double>::On(int, double)'
    Face.cpp:(.text+0x42a): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x440): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x45d): undefined reference to `Vecteur<double>::On(int, double)'
    Face.cpp:(.text+0x470): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x486): undefined reference to `Vecteur<double>::At(int) const'
    Face.cpp:(.text+0x4a3): undefined reference to `Vecteur<double>::On(int, double)'
    Face.i686-pc-linux-gnu..o: In function `Face::AireTriangle(std::vector<Noeud, std::allocator<Noeud> >) const':
    Face.cpp:(.text+0x769): undefined reference to `Vecteur<double>::Vecteur(double, double, double)'
    Face.cpp:(.text+0x844): undefined reference to `Vecteur<double>::Vecteur(double, double, double)'
    Face.cpp:(.text+0x85d): undefined reference to `Vecteur<double>::PVect(Vecteur<double> const&) const'
    Face.cpp:(.text+0x86b): undefined reference to `Vecteur<double>::Norme() const'
    Face.i686-pc-linux-gnu..o: In function `Face::calcTermConvO2(double, double, std::vector<Vecteur<double>, std::allocator<Vecteur<double> > > const*) const':
    Face.cpp:(.text+0xba8): undefined reference to `Vecteur<double>::PScal(Vecteur<double> const&) const'
    Face.cpp:(.text+0xc22): undefined reference to `Vecteur<double>::PScal(Vecteur<double> const&) const'
    Face.i686-pc-linux-gnu..o: In function `Face::CalcTermDiffu(double, double, std::vector<Element, std::allocator<Element> > const*) const':
    Face.cpp:(.text+0xd22): undefined reference to `Vecteur<double>::Norme() const'
    


    avec l'include :
    In file included from include/Vecteur.h:5,
                     from include/Element.h:5,
                     from Element.cpp:1:
    include/../Vecteur.cpp:5: erreur: expected constructor, destructor, or type conversion before «<» token
    include/../Vecteur.cpp:9: erreur: expected constructor, destructor, or type conversion before «<» token
    include/../Vecteur.cpp:16: erreur: expected constructor, destructor, or type conversion before «<» token
    include/../Vecteur.cpp:24: erreur: expected initializer before «<» token
    include/../Vecteur.cpp:30: erreur: expected initializer before «<» token
    include/../Vecteur.cpp:36: erreur: expected initializer before «<» token
    include/../Vecteur.cpp:41: erreur: expected constructor, destructor, or type conversion before «<» token
    include/../Vecteur.cpp:48: erreur: expected constructor, destructor, or type conversion before «<» token
    include/../Vecteur.cpp:54: erreur: expected initializer before «<» token
    include/../Vecteur.cpp:59: erreur: expected initializer before «<» token
    


    Par raport aux undefined reference, les autres classe ont bien les include de Vecteur.h.

    Quelqu'un as une idée..?
    • Partager sur Facebook
    • Partager sur Twitter
      23 juin 2008 à 17:41:08

      La réponse dans la FAQ C++ de développez.
      • Partager sur Facebook
      • Partager sur Twitter
      C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
        23 juin 2008 à 18:02:37

        Merci, j'ai vu ( finalement c'est presque ce que j'ai fait)

        Un problème de reglé.

        Mais qu'un est-il des "expected initialyzer..."
        • Partager sur Facebook
        • Partager sur Twitter
          23 juin 2008 à 18:09:44

          De base, il ne faut pas faire de using dans un .h.
          Si en plus un "using namespace std" (qu'il ne faut pas faire) intervient avant l'inclusion d'un fichier de la bibliothèque standard, les chances de réussir à compiler deviennent très minimes.
          • Partager sur Facebook
          • Partager sur Twitter
          C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
            24 juin 2008 à 10:00:21

            Ouai j'ai cru voir ça...

            Je fait donc un using std::vector dans le .tpp ?

            Pourquoi ne pas mettre using namaspace std? je vous avoue qu'on m'apprend ça depuis un an...
            • Partager sur Facebook
            • Partager sur Twitter
              24 juin 2008 à 10:18:59

              Pas dans un .h, JAMAIS dans un .h, ni quoique ce soit qui puisse être inclus. Dans un .cpp si cela te fais plaisir, personnellement je ne pratique même pas.
              1- Pour éviter les conflits de noms (cf la FAQ de développez)

              2- Pour ne pas emmêler les compilos qui tentent de rajouter de nouvelles des choses dans un espace de noms déjà importé.
              • Partager sur Facebook
              • Partager sur Twitter
              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.

              [Template]Expected constructor.../Undefined reference

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown