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 :

Problèmes écriture de classes templates - Compatibilité VS2008 / g++


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 119
    Billets dans le blog
    148
    Par défaut Problèmes écriture de classes templates - Compatibilité VS2008 / g++
    Bonjour,

    Encore une fois, j'ai de gros problèmes lors de l'écriture de ma classe template.

    Voici ma classe:
    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
     
    #include <list> 
    #include <map> 
    #include <string> 
    #include <typeinfo> 
    #include <cassert> 
     
    #include "Game/UnitTemplate.h" 
    #include "Game/UnitTemplateFactionList.h" 
     
    #include "Utils/Logger.h" 
    #include "Utils/Exceptions/LibraryException.h" 
     
    template <typename T> 
    class Library 
    { 
    private: 
     
        std::map < std::string, T* > entries;   /*!< */ 
     
    public: 
     
        ~Library() 
        { 
            for ( std::map< std::string, T* >::iterator itPair = entries.begin() ; itPair != entries.end() ; ++itPair ) 
            { 
                delete (itPair->second); 
            } 
     
            LDebug << "Library of " << typeid(T).name() << " free"; 
        } 
     
        void add(const std::string& name, T* const value) 
        { 
            if ( this->exists(name) ) 
            { 
                LWarning << "Library will overwrite the key '" << name << "'"; 
            } 
            entries[name] = value; 
        } 
     
        const T* get(const std::string& name)const 
        { 
            std::map<std::string, T*>::const_iterator itT = entries.find(name); 
     
            if (itT == entries.end()) 
            { 
                throw LibraryException("Element '" + name + "' not found"); 
            } 
     
            return itT->second; 
        } 
     
        bool exists(const std::string& name)const 
        { 
            if ( entries.count(name) != 0 ) 
            { 
                return true; 
            } 
     
            return false; 
        } 
     
        // template <typename T> 
        void getValues(std::list< const T* >* pListItems)const 
        { 
            for (std::map< std::string, T* >::const_iterator itItem = entries.begin() ; 
                 itItem != entries.end() ; ++itItem ) 
            { 
                pListItems->push_back(itItem->second); 
            } 
        } 
    }; 
     
    //template <> 
    //class Library<UnitTemplate> 
    //{ 
    //private: 
     
        //std::map < std::string, UnitTemplateFactionList* > entries;     /*!< */ 
     
    //public: 
     
        //~Library() 
        //{ 
            //for ( std::map< std::string, UnitTemplateFactionList* >::iterator itPair = entries.begin() ; itPair != entries.end() ; ++itPair ) 
            //{ 
                //delete (itPair->second); 
            //} 
     
            //LDebug << "Library of " << typeid(UnitTemplateFactionList).name() << " free"; 
        //} 
     
        //void add(const std::string& name, UnitTemplate* const value) 
        //{ 
            //if ( !this->exists(name) ) 
            //{ 
                //entries[name] = new UnitTemplateFactionList(); 
                //if ( entries[name] == NULL ) 
                //{ 
                    //LError << "Fail to allocate memory for UnitTemplateFactionList"; 
                    //throw std::bad_alloc("UnitTemplateFactionList allocation failed"); 
                //} 
            //} 
     
            //entries[name]->add(value); 
        //} 
     
        //const UnitTemplateFactionList* get(const std::string& name)const 
        //{ 
            //std::map<std::string, UnitTemplateFactionList*>::const_iterator itT = entries.find(name); 
     
            //if (itT == entries.end()) 
            //{ 
                //return NULL; 
            //}// ToDO throw exception ? 
     
            //return itT->second; 
        //} 
     
        //bool exists(const std::string& name)const 
        //{ 
            //if ( entries.find(name) != entries.end() ) 
            //{ 
                //return true; 
            //} 
     
            //return false; 
        //} 
     
        //template <typename T> 
        //void getValues(std::list< const UnitTemplateFactionList* >* pListItems)const 
        //{ 
            //for (std::map< std::string, UnitTemplateFactionList* >::const_iterator itItem = entries.begin() ; 
                 //itItem != entries.end() ; ++itItem ) 
            //{ 
                //pListItems->push_back(itItem->second); 
            //} 
        //} 
    //};
    Le compilateur (g++ 4.4) me donne les erreurs suivantes:
    In file included from Engine/Library.cpp:25:
    Engine/Library.h: In destructor ‘Library<T>::~Library()’:
    Engine/Library.h:51: error: expected ‘;’ before ‘itPair’
    Engine/Library.h:51: error: ‘itPair’ was not declared in this scope
    Engine/Library.h: In member function ‘const T* Library<T>::get(const std::string&) const’:
    Engine/Library.h:70: error: expected ‘;’ before ‘itT’
    Engine/Library.h:72: error: ‘itT’ was not declared in this scope
    Engine/Library.h:77: error: ‘itT’ was not declared in this scope
    Engine/Library.h: In member function ‘void Library<T>::getValues(std::list<const T*, std::allocator<const T*> >*) const’:
    Engine/Library.h:93: error: expected ‘;’ before ‘itItem’
    Engine/Library.h:94: error: ‘itItem’ was not declared in this scope
    Mon plus gros problème, c'est que je crois que ce code compile sous VS 2008.
    Je souhaite vraiment avoir un code compatible avec les deux compilateurs.

    Ce qui me chagrine, c'est que le compilateur indique comme quoi T n'est pas défini, pourtant le template <typename T>.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 035
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 035
    Par défaut
    Salut.
    Il faut ajouter des typename.
    http://cpp.developpez.com/faq/cpp/?p...LATES_typename

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 119
    Billets dans le blog
    148
    Par défaut
    Citation Envoyé par yan Voir le message
    Salut.
    Il faut ajouter des typename.
    http://cpp.developpez.com/faq/cpp/?p...LATES_typename
    En effet, on me l'avais déjà dit, et par erreur, j'ai pris une vieille version de mon code ... donc cette conversation fait un peu doublon.

    Par contre, j'ai une vraie nouvelle question, car j'ai un problème sur la spécialisation d'une fonction dans un template (et encore avec la compatibilité VS / g++)

    Voici mon code qui compile sous g++, malheureusement, il n'est pas exécuté.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <char> 
        char getAs(const std::string& name)const 
        { 
            std::cout << "Using char specialisation" << std::endl; 
            std::string charString(this->get(name)); // Can throw ParameterNotFoundParamsException 
            if ( charString.size() != 1 ) 
            { 
                throw InvalidConvertionParamsException(name); 
            } 
     
            return charString[0]; 
        }
    Lorsque je suis avec VS, j'utilise cette variante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    template <> 
        char getAs<char>(const std::string& name)const 
        { 
            std::string charString(this->get(name)); // Can throw ParameterNotFoundParamsException 
            if ( charString.size() != 1 ) 
            { 
                throw InvalidConvertionParamsException(name); 
            } 
     
            return charString[0]; 
        }
    Qui est correctement executée, mais qui ne compile pas sous g++, pour les raisons suivantes:
    In file included from Engine/Params.cpp:25:
    Engine/Params.h:80: error: explicit specialization in non-namespace scope ‘class Params’
    Engine/Params.h:81: error: template-id ‘getAs<char>’ in declaration of primary template
    Engine/Params.h:93: error: too many template-parameter-lists
    Le code entier est le suivant:
    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
     
    class Params 
    { 
    private: 
     
        std::map < std::string, std::string > params;   /*!< */ 
     
    public: 
     
        void add(const std::string& name, const std::string& value); 
        void remove(const std::string& name); 
     
        bool exists(const std::string& name)const; 
     
        const std::string& get(const std::string& name)const; 
     
        template <typename T> 
        T getAs(const std::string& name)const 
        { 
            std::stringstream ss (this->get(name)); // Can throw ParameterNotFoundParamsException 
            T value; 
     
            ss >> value; 
     
            return value; 
        } 
     
        template <> 
        char getAs<char>(const std::string& name)const 
        { 
            std::string charString(this->get(name)); // Can throw ParameterNotFoundParamsException 
            if ( charString.size() != 1 ) 
            { 
                throw InvalidConvertionParamsException(name); 
            } 
     
            return charString[0]; 
        } 
     
        template <typename T> 
        T getAs(const std::string& name, const T defaultValue)const 
        { 
            if ( this->exists(name) ) 
            { 
                std::stringstream ss(this->get(name)); 
                T value; 
     
                ss >> value; 
     
                return value; 
            } 
            else 
            { 
                return defaultValue; 
            } 
        } 
    };
    Merci pour votre aide
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Bonsoir,

    Les spécialisations doivent se faire dans un namespace pas dans une classe, sort tes spécialisations.

    A la lecture de la norme (C++2011) je dirais que c'est VC++ qui a tort, mais je n'en suis pas certain.

  5. #5
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 119
    Billets dans le blog
    148
    Par défaut
    Merci pour la réponse.

    J'ai mis la chose suivante dans .cpp

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    template <> 
    char Params::getAs<char>(const std::string& name)const 
    { 
        std::cout << "Blob" << std::endl; 
        std::string charString(this->get(name)); // Can throw ParameterNotFoundParamsException 
        if ( charString.size() != 1 ) 
        { 
            throw InvalidConvertionParamsException(name); 
        } 
     
        return charString[0]; 
    }
    Et le fichier d'entête est maintenant comme suit:
    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
     
    class Params 
    { 
    private: 
     
        std::map < std::string, std::string > params;   /*!< */ 
     
    public: 
     
        void add(const std::string& name, const std::string& value); 
        void remove(const std::string& name); 
     
        bool exists(const std::string& name)const; 
     
        const std::string& get(const std::string& name)const; 
     
        template <typename T> 
        T getAs(const std::string& name)const 
        { 
            std::stringstream ss (this->get(name)); // Can throw ParameterNotFoundParamsException 
            T value; 
     
            ss >> value; 
     
            return value; 
        } 
     
        // char getAs<char>(const std::string& name)const; 
     
     
        template <typename T> 
        T getAs(const std::string& name, const T defaultValue)const 
        { 
            if ( this->exists(name) ) 
            { 
                std::stringstream ss(this->get(name)); 
                T value; 
     
                ss >> value; 
     
                return value; 
            } 
            else 
            { 
                return defaultValue; 
            } 
        } 
    };
    Cela compile (avec g++) mais il n'y a toujours pas d'appel à la fonction spécialisée.

    Les spécialisations doivent se faire dans un namespace pas dans une classe, sort tes spécialisations.
    Hum, j'ai un peu de mal à comprendre. Comme dois-je appeler le namespace ? Comment dois je écrire la fonction dans ce namespace ? Et comment faire le lien avec la classe Params, du coup ?

    (J'ai essayé des petits trucs, mais je n'ai pas trouvé la bonne chose).

    A la lecture de la norme (C++2011) je dirais que c'est VC++ qui a tort, mais je n'en suis pas certain.
    Sachant que je suis avec VS 2008 est que celui-ci n'intègre pas la norme C++2011 ... je ne suis pas sur que l'on puisse dire qu'il a tort ou raison.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2004
    Messages
    1 391
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Par défaut
    Ma phrase voulait dire de faire ce que tu as fais, tu as mis la spécialisaiton dans le namespace global alors qu'avant elle était dans la classe Params.

    Pas de séparation header/cpp pour les templates (pas comme ca du moins), mets ta spécialisation après la définition de ta classe dans le header.

    En effet VS n'est pas en respect total avec la dernière norme du C++ (comme tout les compilateurs à l'heure actuelle), mais je ne crois pas que cette partie spécifique des templates ai changé, mais je peux me tromper (il faudrait vérifier dans l'ancienne norme).

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

Discussions similaires

  1. Avis sur un problème de "friend class template"
    Par metagoto dans le forum C++
    Réponses: 8
    Dernier message: 24/03/2010, 17h16
  2. [Template] Problème Classe Template
    Par gimpycpu dans le forum Langage
    Réponses: 7
    Dernier message: 23/05/2007, 05h10
  3. problème classes templates...
    Par youp_db dans le forum C++
    Réponses: 3
    Dernier message: 02/11/2005, 13h04
  4. Problèmes de fonctions membres de classe templates, gcc3.3.6
    Par yves.dessertine dans le forum Autres éditeurs
    Réponses: 12
    Dernier message: 17/10/2005, 21h36
  5. [DLL/classe template] problème de link
    Par Bob.Killer dans le forum C++
    Réponses: 7
    Dernier message: 31/08/2005, 18h56

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