1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 543
    Points : 9 334
    Points
    9 334
    Billets dans le blog
    1

    Par défaut Erreur de template dépendante du compilateur

    Bonjour,

    J'ai une application GUI qui fonctionne bien. Dans ma hiérarchie, j'ai une classe abstraite qui est la classe mère des différents menus (ceux qui affichent une liste sélectionnable). Je souhaite transformer cette classe en classe template dont le paramètre est le nombre d'éléments dans la liste à afficher. Je n'ai pas droit de faire de l'allocation dynamique d'où cette approche template pour dimensionner le tableau contenant les éléments. J'ai donc fait cette transformation et me retrouve dans une situation où mon code compile avec Visual Studio, avec IAR Embedded Workbench, mais plus avec MinGW. Il y a une erreur laconique sur l'appel d'une fonction template dans la classe template.

    Je me suis battu pour arriver à un code minimaliste reproduisant le problème qui me confirme que Visual Studio accepte ce code que MinGW refuse. Je n'ai pas retesté ce code minimal avec IAR. Ici, je vois deux solutions :
    • un bug dans MinGW
    • un comportement non portable que MinGW refuse


    Comme l'erreur est non explicite, je fais appel à votre expertise. Il y a beaucoup de fichiers, merci de votre patience

    Page.hpp, qui contient la classe mère de toutes les pages et l'objet permettant de faire la navigation.
    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #ifndef PAGE_HPP
    #define PAGE_HPP
     
    class MyApplication
    {
    public:
        template<class NextPage>
        void gotoPage()
        {
        }
    };
     
    class Page
    {
    public:
        virtual ~Page()
        {
        }
     
        virtual void handleEvent() = 0;
     
        MyApplication& getApplication()
        {
            static MyApplication application;
            return application;
        }
    };
     
    #endif
    TempateMenuPage.hpp avec la fameuse classe template. Comme toutes les pages de menu doivent retourner à la page d'accueil, je met le gotoPage() dans cette classe. C'est ça qui pose soucis.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #include "HomePage.hpp"
    #include "Page.hpp"
     
    template<int itemCount>
    class TempateMenuPage : public Page
    {
    public:
        void handleEvent() override
        {
            getApplication().gotoPage<HomePage>();
        }
    };
    MainMenuPage.hpp qui spécialise le template
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "TempateMenuPage.hpp"
     
    class MainMenuPage : public TempateMenuPage<5>
    {
    public:
        void handleEvent() override;
    };
    MainMenuPage.cpp (je remet le gotoPage() pour tester et ici ça ne pose pas problème).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    #include "MainMenuPage.hpp"
     
    void MainMenuPage::handleEvent()
    {
        getApplication().gotoPage<HomePage>();
    }
    HomePage.hpp qui définit la page utilisée dans la classe template
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    #include "Page.hpp"
     
    class HomePage : public Page
    {
    public:
        void handleEvent() override;
    };
    HomePage.cpp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #include "HomePage.hpp"
     
    void HomePage::handleEvent()
    {
    }
    Et enfin, l'erreur magique :
    g++ -std=c++11 "-IC:\\Users\\X-pigradot\\workspaceTests\\Experiences\\src" "-IC:\\Users\\X-pigradot\\workspaceTests\\Experiences" -O0 -g3 -pedantic -Wall -Wextra -c -fmessage-length=0 -o "src\\MainMenuPage.o" "..\\src\\MainMenuPage.cpp" 
    In file included from ..\src\MainMenuPage.hpp:1:0,
                     from ..\src\MainMenuPage.cpp:1:
    ..\src\TempateMenuPage.hpp: In member function 'void TempateMenuPage<itemCount>::handleEvent()':
    ..\src\TempateMenuPage.hpp:10:43: error: expected primary-expression before '>' token
             getApplication().gotoPage<HomePage>();
                                               ^
    ..\src\TempateMenuPage.hpp:10:45: error: expected primary-expression before ')' token
             getApplication().gotoPage<HomePage>();
         
    Qu'en pensez-vous ?

    Merci d'avance !

  2. #2
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 543
    Points : 9 334
    Points
    9 334
    Billets dans le blog
    1

    Par défaut

    PS : je partage aussi les fichiers pour ceux qui voudraient compiler le code plus facilement ^^
    Fichiers attachés Fichiers attachés

  3. #3
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 947
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 947
    Points : 16 426
    Points
    16 426

    Par défaut

    Je n'ai pas le temps de vérifier scrupuleusement, mais a priori, tu as un problème d'ordre d'inclusion de tes fichiers.
    simule le préprocesseur à la main, tu devrais voir.

    Au passage, je te rappelle la règle: une template doit être intégralement définie lors de son instanciation.
    (un rappel fait toujours du bien )
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 543
    Points : 9 334
    Points
    9 334
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par ternel Voir le message
    Je n'ai pas le temps de vérifier scrupuleusement, mais a priori, tu as un problème d'ordre d'inclusion de tes fichiers.
    simule le préprocesseur à la main, tu devrais voir.
    Si tu parles des lignes 1 et 2 de TempateMenuPage.hpp, ce n'est pas la cause du problème.

    Citation Envoyé par ternel Voir le message
    Au passage, je te rappelle la règle: une template doit être intégralement définie lors de son instanciation.
    (un rappel fait toujours du bien )
    Je présume que tu me rappelles cette règle car je ne dois pas la respecter... Peut-tu expliciter pour mon cas stp ?

  5. #5
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 947
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 947
    Points : 16 426
    Points
    16 426

    Par défaut

    Pour le rappel, non, c'est préventif. Quand on a un problème de template, il vaut toujours mieux se la remémorer.

    En général, quand gcc se plaint sur un "before >", c'est qu'il n'a pas l'idée que le nom de la template est une template, et que du coup, l'analyse syntaxique amorce une comparaison arithmétique (autour du < ouvrant)
    Il analyse getApplication().gotoPage<HomePage>() comme ( getApplication().gotoPage < HomePage ) > (). Évidemment, ca ne veut rien dire.

    Et la, j'ai l'illumination.

    tu es dans une template, et tu appelles une fonction membre template.
    la syntaxe est getApplication().template gotoPage<HomePage>(). Have fun with C++.
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 543
    Points : 9 334
    Points
    9 334
    Billets dans le blog
    1

    Par défaut



















    Je m'étais douté que le double template aidait pas. Dans ma tentative de reproduction, j'avais essayé de bypasser la classe MyApplication et d'avoir une fonction membre template gotoPage() dans Page mais le problème se ne posait pas. Du coup, je m'étais éloigné de cette hypothèse du double template... Ca corrige mon problème. Merci !

    J'ai quand même voulu comprendre un peu ce qu'il se passe. On trouve plusieurs discussions stackoverflow sur le sujet, celle-ci étant peut-être la plus claire. On retrouve souvent cette citation de la norme :
    Citation Envoyé par C++'03 Standard 14.2/4:
    When the name of a member template specialization appears after . or -> in a postfix-expression, or after nested-name-specifier in a qualified-id, and the postfix-expression or qualified-id explicitly depends on a template-parameter (14.6.2), the member template name must be prefixed by the keyword template. Otherwise the name is assumed to name a non-template.
    Si je décortique cette affirmation par rapport à mon code, j'ai dû mal trouver les correspondances... Je prend cette partie "the member template name must be prefixed by the keyword template" et je m'étonne car getApplication() n'est pas un membre template (member template, template member ?)

  7. #7
    Expert éminent sénior

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    juin 2007
    Messages
    4 947
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : juin 2007
    Messages : 4 947
    Points : 16 426
    Points
    16 426

    Par défaut

    La définition qui pose problème est celle dans TemplateMenuPage qui est une template de classe.
    Donc son this est template, et tout en découle.

    La citation correspond à "si le bidule apparaissant ., -> ou ::, est le nom d'une template, et qu'il recoit explicitement un parametre template, il faut préciser que c'est une template".

    en gros, Truc . Bidule_template < parametre > n'est pas valide, il faut préciser Truc . template Bidule_template < parametre >.

    Par contre, si les parametres templates sont déduits, ca passe: Truc . Bidule_template(Machin_qui_donne_le_parametre).
    Mes principes de bases du codeur qui veut pouvoir dormir:
    • Une variable de moins est une source d'erreur en moins.
    • Un pointeur de moins est une montagne d'erreurs en moins.
    • Un copier-coller, ça doit se justifier... Deux, c'est un de trop.
    • jamais signifie "sauf si j'ai passé trois jours à prouver que je peux".
    • La plus sotte des questions est celle qu'on ne pose pas.
    Pour faire des graphes, essayez yEd.
    le ter nel est le titre porté par un de mes personnages de jeu de rôle

  8. #8
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 543
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 543
    Points : 9 334
    Points
    9 334
    Billets dans le blog
    1

    Par défaut

    Citation Envoyé par ternel Voir le message
    Have fun with C++.
    Je crois que tu résumes bien la situation

    Merci beaucoup !

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

Discussions similaires

  1. [templates][debutant]erreur "shadows template param"
    Par Gotmere dans le forum Langage
    Réponses: 3
    Dernier message: 12/12/2007, 23h30
  2. [TBS] erreur systeme template
    Par snyfir dans le forum Templates
    Réponses: 4
    Dernier message: 27/06/2007, 10h02
  3. erreur du template joomla 1.5
    Par phpieur dans le forum Joomla
    Réponses: 12
    Dernier message: 24/02/2007, 11h15
  4. Erreur Gcc, template et iterator
    Par aidos dans le forum Langage
    Réponses: 7
    Dernier message: 14/03/2006, 09h04
  5. Erreur de template
    Par Clad3 dans le forum Langage
    Réponses: 4
    Dernier message: 13/03/2005, 15h22

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