IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

Permissivité du compilateur avec les templates ?


Sujet :

Langage C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut Permissivité du compilateur avec les templates ?
    Bonjour à tous,

    Aujourd'hui je me suis rendu compte que gcc permettait la compilation d'un code qui comporte une erreur au runtime. J'aimerais savoir comment le compilateur interprète ce code et pourquoi il laisse passer cette erreur.

    J'ai deux classes QValues et PQuanta:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     template<typename PDT>
      class QValues{
     
      public:
     
        //la fonction est bidon, je montre juste un fragment du code intéressant
        void append(const vector<vector<vector<PDT> > >& vvv, pair<PDT,PDT> p_ab){
            int n = 0;
            for(unsigned int nc=1; nc<vvv_val_[n].size(); nc++) {
                //la ligne suivate ne devrait pas compiler car j'essaie de multiplier un vector<PDT> par un PDT, ce qui n'est pas permis il me semble
    	    vvv[n][nc] *= p_ab.first;
    	}
        }
     
    //Voici ma deuxieme classe:
     
       class PQuanta : public QValues<double> {
     
        }
    J'ai enlevé beaucoup de code mais l'important est que chez moi cela compile et je ne comprend pas pourquoi, je pensais que gcc remplaçait PDT par double et donc ça revient à faire le même calcul que:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    vector<double> v(10, 5.0);
    v *= 2;
    Or cette opération ne compile pas car l'opérateur *= n'est pas défini pour cette opération, alors pourquoi gcc accepte de compiler l'opération dans le code précédent ? Est-du au paramètre template ?

    Merci d'avance de vos réponses

  2. #2
    screetch
    Invité(e)
    Par défaut
    sous GCC les templates sont créés partiellement, seules les fonctions appelées sont instanciées. le code n'est pas compilé tant que tu n'appelles pas donc pas d'erreur.
    Sous visual studio, le code n'est même pas vérifié tant que le template n'est pas instancié, si tu ecris n'importe quoi dans un template qui n'est pas utilisé ca compilera quand même. Par contre des qu'une classe template est instancié, toute ses méthodes sont instanciées au contraire de GCC. D'où l'erreur.

  3. #3
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Par contre des qu'une classe template est instancié, toute ses méthodes sont instanciées au contraire de GCC.
    T'as des sources pour ça? Parce que c'est pas standard comme comportement... (imagine le bloat... :' )
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Bonjour et merci de ta réponse
    Pourrais-tu développer un peu cette phrase "sous GCC les templates sont créés partiellement" ?

    Est-ce que ça veut dire que quand on utilise des containers gcc se limite au type du container et ne se préoccupe du type contenu qu'a l'instanciation ?

    Par exemple pour un vector<ObjetLambda> comment cela se passe ?

  5. #5
    screetch
    Invité(e)
    Par défaut
    oui apparemment j'ai menti, elles sont juste compilées, apparemment juste pour le plaisir puisqu'elles ne finissent pas dans le fichier compilé.

  6. #6
    screetch
    Invité(e)
    Par défaut
    ce que je voulais dire par la, c'est que tant qu'on appelle pas push_back, la méthode push_back n'est pas instanciée.
    Sous GCC, si elle ne compile pas, c'est même pas grave.
    En revanche, sous visual studio, si elle ne compile pas, c'est plus grave.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Février 2007
    Messages
    206
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 206
    Points : 79
    Points
    79
    Par défaut
    Peut-on m'expliquer la création "partielle" des templates sous gcc ?

  8. #8
    screetch
    Invité(e)
    Par défaut
    c'est en fait presque la même sous GCC et Visual Studio, sauf que visual studio pousse la compilation un peu plus loin.

    Lorsque tu as une classe template avec, mettons, deux methodes dedans, la "classe" est instanciée, mais pas ses méthodes (pas tout de suite). Le compilateur génère donc le stockage.
    Toute les méthodes virtuelles sont instanciées immédiatement, celles la on ne peut pas y couper

    donc dans une classe:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    template< typename Pouet > class Ptr
    {
      Pouet* m_ptr;
    public:
      Ptr() { m_ptr = nullptr; }
      Ptr(Pouet* p) { m_ptr = p; }
      virtual ~Ptr(); // c'est pour l'exemple, faites pas ca chez vous
    };
    lorsque le compilateur voit:

    il va:
    - générer (instancier) la classe Ptr (dans le sens, son stockage, la taille de Pouet*)
    - générer la méthode virtuelle ~Ptr (pas le choix)
    dans un deuxieme temps, puisqu'on fait appel au constructeur par défaut, il va instancier Ptr<Pouet>:tr() puisqu'il en a besoin

    comme on a pas besoin de la troisième méthode, il s'en fout.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. wpf: probleme avec les templates
    Par mk.wassim dans le forum Windows Presentation Foundation
    Réponses: 3
    Dernier message: 18/03/2009, 17h54
  2. [Smarty] Debut avec les templates
    Par Arnich dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 22/11/2007, 18h35
  3. probleme avec les templates d'un formview
    Par devdotnet dans le forum ASP.NET
    Réponses: 2
    Dernier message: 01/11/2007, 09h32
  4. Erreur de link avec les templates
    Par suiss007 dans le forum C++
    Réponses: 6
    Dernier message: 04/01/2007, 11h09
  5. Probleme avec les templates
    Par TeC_MaN dans le forum C++
    Réponses: 2
    Dernier message: 08/01/2006, 14h53

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo