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 :

Classe et Template


Sujet :

Langage C++

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 5
    Points : 1
    Points
    1
    Par défaut Classe et Template
    Bonjour,

    j'ai un petit probleme du a un passage de gcc3.2.3 a un gcc plus recent.
    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
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
     
    HPP FILE :
     
    template <typename _EnumType, unsigned int _enumCount>
    class myTopClass
    {
        public:
            inline static const std::string &GetClassName  (                       ) { return CLASS_NAME;       }
            inline static const std::string &GetName       (_EnumType id           ) { return Names[id];        }
            inline static unsigned int       GetDefaultSize(_EnumType id           ) { return DefaultSizes[id]; }
            inline static _EnumType          GetId         (const std::string &name);
            template <class _FinalType>
             static void InitializeArray(_FinalType  array[]);
            template <class _FinalType>
             static void InitializeArray(_FinalType* array[]);
     
            inline myTopClass() {}
            inline virtual ~myTopClass() {}
            inline myTopClass(_EnumType id) { setId(id); }
            inline _EnumType          id  () const { return m_id         ; }
            inline const std::string &name() const { return GetName(id()); }
            inline unsigned int       size() const { return m_size       ; }
            inline void setSize(unsigned int size) { m_size = size       ; }
     
        protected:
            static void Define(_EnumType id, const std::string &name, unsigned int defaultSize);
     
            inline void setId(_EnumType id) { m_id = id; setSize(GetDefaultSize(id)); }
     
            static const std::string                CLASS_NAME;
            static std::map<std::string, _EnumType> EnumFromName;
            static std::string                      Names[_enumCount];
            static unsigned int                     DefaultSizes[_enumCount];
     
            // protected attributes
            _EnumType    m_id;
            unsigned int m_size;
    };
    ......
    class botClassA: public myTopClass<Register, REGISTER_COUNT>
    {
        public:
                   static void         Initialize();
            inline static unsigned int GetAddress(Register reg) { return Addresses[reg]; }
     
            inline botClassA() {}
                   virtual ~botClassA();
            inline botClassA(Register reg) : myTopClass<Register, REGISTER_COUNT>(reg) {}
            inline unsigned int address() const { return GetAddress(id()); } ///< instance accessor for convenience
     
        protected:
            static unsigned int Addresses[REGISTER_COUNT];
    };
     
    class botClassB: public myTopClass<CtrlCField, CCFIELD_COUNT>
    {
        public:
            static void Initialize();
            static void ComputeLsbsInArray(botClassB array[]);
     
    	//inline botClassB() {}
    	virtual ~botClassB();
            inline unsigned int lsb() const { return m_lsb; }
     
        protected:
            inline unsigned int &lsb() { return m_lsb; } ///< write access is protected ; only ComputeLsbsInArray() can set it
     
            unsigned int m_lsb;
    };
    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
    30
     
    CPP FILE : 
    // botClassA class attributes
    /*work for GCC 3.2.3
    unsigned int botClassA::Addresses[REGISTER_COUNT];*/
    template<> unsigned int botClassA::Addresses[REGISTER_COUNT];
     
    // botClassA class attributes (inherited from topClass template)
    /*work for GCC 3.2.3
    const std::string                  myTopClass<Register, REGISTER_COUNT>::CLASS_NAME("botClassA");
    std::map<std::string, Register> myTopClass<Register, REGISTER_COUNT>::EnumFromName;
    std::string                        myTopClass<Register, REGISTER_COUNT>::Names[REGISTER_COUNT];
    unsigned int                       myTopClass<Register, REGISTER_COUNT>::DefaultSizes[REGISTER_COUNT];*/
    template<> 		const std::string                  myTopClass<Register, REGISTER_COUNT>::CLASS_NAME("botClassA");
    template<> 		std::map<std::string, Register> myTopClass<Register, REGISTER_COUNT>::EnumFromName;
    template<> 		std::string                        myTopClass<Register, REGISTER_COUNT>::Names[REGISTER_COUNT];
    template<> 		unsigned int                       myTopClass<Register, REGISTER_COUNT>::DefaultSizes[REGISTER_COUNT];
     
     
     
    // botClassB class attributes (inherited from topClass template)
    /*work for GCC 3.2.3
    const std::string                   myTopClass<CtrlCField, CCFIELD_COUNT>::CLASS_NAME("botClassB");
    std::map<std::string, CtrlCField> myTopClass<CtrlCField, CCFIELD_COUNT>::EnumFromName;
    std::string                         myTopClass<CtrlCField, CCFIELD_COUNT>::Names[CCFIELD_COUNT];
    unsigned int                        myTopClass<CtrlCField, CCFIELD_COUNT>::DefaultSizes[CCFIELD_COUNT];*/
    template<> 		const std::string                   myTopClass<CtrlCField, CCFIELD_COUNT>::CLASS_NAME("botClassB");
    template<> 		std::map<std::string, CtrlCField> myTopClass<CtrlCField, CCFIELD_COUNT>::EnumFromName;
    template<> 		std::string                         myTopClass<CtrlCField, CCFIELD_COUNT>::Names[CCFIELD_COUNT];
    template<>  		unsigned int                        myTopClass<CtrlCField, CCFIELD_COUNT>::DefaultSizes[CCFIELD_COUNT];
    Avec le gcc3.2.3 aucun probleme de compilation et d'execution du program.
    Avec gcc3.4.6, probleme a la compilation "error : too few template-parameter-lists problem sur les lignes identifiees dans le code ci dessus.
    J'ai donc ajoute "template<>" en debut de chaque ligne, ce qui m'a permis d'avoir une compilation OK
    Code pour GCC3.2.3 commente et remplace par le code pour le GCC3.4.6
    Malheureusement, au chargement du program j'ai l'erreur ci apres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ERROR:TestExec: Can not load the library XXX.so (XXX.so: undefined symbol: _ZN12myTopClassI12CtrlCFieldLj15EE12DefaultSizesE)
    J'ai beau chercher mais je ne comprends pas ce qui peut poser un probleme ici.

    Si une bonne ame pouvait se pencher sur ce probleme, cela me serait d'une grande utilite.
    Merci

  2. #2
    Membre actif Avatar de SKone
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2004
    Messages
    333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 333
    Points : 250
    Points
    250
    Par défaut
    Bonjour,

    La seconde zone de code est un fichier cpp ? h ?

    Je crois comprendre que vous compilez une library *.so et l'utilisez dans un exécutable ?
    Si c'est bien ça il faut exporter chaque spécialisation de la template.

    C'est triste mais via gcc fait tout ce qu'il peut pour ne pas simplifier le travail.
    Soit exporter en C-Style avec des "CreateInstance" etc

    Je ne vois pas dans le bout de code l'export des classes:
    Code cpp : Sélectionner tout - Visualiser dans une fenêtre à part
    template class __declspec(dllimport) std::vector<int>;

    http://cpp.developpez.com/faq/cpp/?p...eque-dynamique

    Sans plus d'info je ne peux pas trop aider.

    Bon courange

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour et merci SKone pour votre reponse.

    la deuxieme partie du code est effectvement dans un fichier cpp.

    En fait au depart, tout ceci sert a creer une librairie .a que j'utilise ensuite dans un programme.
    Celui ci est alors compile (.so) avec comme depence cette librairie .a.

    Au moment de la compilation de la librairie, avec gcc3.2.3, pas de soucis, alors qu'avec gcc3.4.6, il y avait ces erreurs de too few template-parameter-lists.

    J'ai donc modifier le cpp afin de respecter la definition correcte de ces specialisations.
    LA compilation sous gcc3.4.6 s'est alors deroulee sans soucis, que ce soit la compilation de la librairie .a, ou la compilation de mon program .so.

    Par contre au moment du chargement de mon program a travers un executable, j'ai systematiquement cette erreur de "undefined symbol".

    Ce que je pensais, c'est qu'en realisant une librairie .a avec ces templates, je n'aurais pas soucis d'utilisation avec mon programme.
    Me suis je fourvoye ?

    Quelle serait la methode pour rendre ceci accessible a tous ?

  4. #4
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Dans ton .h, rajoute :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template <typename _EnumType, unsigned int _enumCount>
    unsigned int myTopClass<_EnumType, _enumCount> DefaultSizes[_enumCount];
    (et idem pour tous tes membres statiques).

    Cela dit, je pense que le fond du problème est que ta spécialisation n’est pas exportée. Du coup, peut-être que ça règlera ton problème de link, mais pas sûr que ça n’introduise pas d’autres soucis comme le classname qui ne serait pas bon. Et je ne sais pas si gcc 3.4.6 supporte « extern template » tel qu’il est défini dans la dernière norme.

    Sinon, vu ton code, je pense qu’un CRTP est la bonne solution.

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour white_tentacle,

    merci pour ta reponse;
    deux petites questions :
    * dans le cas ou extern template serait accepte par mon compilateur, ou dois je le mettre ? dans le cpp de ma ibrairie .a ou bien dans mon program qui fait reference a cette librairie .a.
    * qu'appelles tu CRTP ?

  6. #6
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    Citation Envoyé par Fred_FFE Voir le message
    Bonjour white_tentacle,

    merci pour ta reponse;
    deux petites questions :
    * dans le cas ou extern template serait accepte par mon compilateur, ou dois je le mettre ? dans le cpp de ma ibrairie .a ou bien dans mon program qui fait reference a cette librairie .a.
    * qu'appelles tu CRTP ?
    Pour extern template class, tu le mets dans le .h. Ça sert juste à déclarer « ce template est spécialisé, j’en fournis une spécialisation quelque part ».

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // dans le .h
    extern template class myTopClass<_EnumType, _enumCount>;
    Ensuite, tu peux, dans ton .cpp, fournir ta spécialisation ou une instanciation explicite au moyen de template class.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    template class myTopClass<_EnumType, _enumCount>;
    Je pense qu’un de tes problèmes est que tu essaies de spécialiser partiellement ton template (à savoir, spécialiser uniquement les membres statiques), ce qui à mon avis est foireux.

    Pour le CRTP, cf l’entrée de la FAQ qui expliquera mieux que moi : http://cpp.developpez.com/faq/cpp/?p...ce-que-le-CRTP

    Ici je verrai bien un truc du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    template <typename _EnumType, unsigned int _enumCount, typename T>
    class myTopClass
    {
           inline static const std::string &GetClassName  (                       ) { return T::CLASS_NAME;       }
    ....
    };
    .....
    class botClassA: public myTopClass<Register, REGISTER_COUNT, botClassA>
    {
    public:
    static std::string CLASS_NAME;
    .....
    };

  7. #7
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    merci, je vais regarder tout ca et voire si je peux m'en sortir.

  8. #8
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2014
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2014
    Messages : 5
    Points : 1
    Points
    1
    Par défaut
    Bonjour white_tentacule,

    Tout d'abord, merci beaucoup car ton aide m'a ete d'un grand secour pour resoudre ceci.

    j'ai finalement implemente la solution de la templatisation des variables dans le hpp.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    template <typename _EnumType, unsigned int _enumCount>
    unsigned int myTopClass<_EnumType, _enumCount>::DefaultSizes[_enumCount];
    Dans un premier temps, j'avais laisse la specialisation dans le cpp.
    Avec le gcc3.4.6, ok pour la compilation ainsi que pour le chargement du programme.
    Par contre, avec le gcc3.2.3, la compilation retournait une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    XXXX/XXXX.cpp:19: conflicting types for `std::string 
     
       myTopClass<Register, 51>::Names[REGISTER_COUNT]'
     
    XXXX/XXXX.hpp:191: previous declaration as `
     
       std::basic_string<char, std::char_traits<char>, std::allocator<char> > 
     
       myTopClass<Register, 51>::Names[51]'
    J'ai donc commente la specialisation dans le cpp.

    J'ai ensuite essaye avec les 2 gcc : la compilation et le chargement du programme se sont faites sans aucun soucis.

    J'en viens donc a me demander si, dans le cas du gcc3.4.6, le compilateur ne tiendrait pas en compte cette specialisation pour une raison qui pourrait etre qu'il ne sait pas quoi en faire ou bien tout simplement qu'il n'y voit pas d'interet.
    Certes ca serait lui donner des capacites qu'il n'a peut etre pas mais ...... ?

    Qu'en penses tu ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/07/2008, 15h06
  2. template<class> et template<typename>
    Par mister3957 dans le forum C++
    Réponses: 10
    Dernier message: 01/11/2007, 09h32
  3. Probleme classe interne template
    Par SOAD08 dans le forum Langage
    Réponses: 5
    Dernier message: 26/03/2007, 14h19
  4. Méthode template dans classe non template ?
    Par shenron666 dans le forum Langage
    Réponses: 12
    Dernier message: 04/09/2006, 17h50
  5. [Template] methode template d'une classe pas template
    Par bigquick dans le forum Langage
    Réponses: 8
    Dernier message: 25/03/2005, 15h09

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