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

SL & STL C++ Discussion :

Nettoyer des std::queue en une fonction template


Sujet :

SL & STL C++

  1. #1
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut Nettoyer des std::queue en une fonction template
    Bonjour,
    j'ai lu que pour vider une std::queue on faisait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    void clear(std::queue <void * > &q)
    {
       std::queue< void * > empty;
       std::swap( q, empty );
    }
    Je voudrais rendre cette fonction template pour la faire fonctionner pour des void* mais aussi des objets de types que j'ai créé.
    J'ai fait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    template <typename T> 
    	void clear(std::queue <T* > &q)
    {
       std::queue< T* > empty;
       std::swap( q, empty );
    }
    Cependant cela ne compile même pas.

    fatal error C1001: INTERNAL COMPILER ERROR
    (compiler file 'msc1.cpp', line 1786)
    Please choose the Technical Support command on the Visual C++
    Help menu, or open the Technical Support help file for more information
    Error executing cl.exe.
    Les template ne s'appliquent ils qu'aux classes ? Ne puis je pas faire ce que je souhaite? Ou y a t'il mieux pour nettoyer une std:queue contenant des objets homogènes quelconques ?

    Merci...

  2. #2
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Hello,

    La ligne qui fait planter, se serait pas celle du swap ?

  3. #3
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut
    en fait ca plante pas, ça compile même pas !
    pourquoi? peut être que le swap n'aime pas le template ?

  4. #4
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Je viens de tester vite fait :

    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
    using namespace std;
     
    template <typename T>
    void clear(queue <T*> &q)
    {
       queue< T* > empty;
       swap( q, empty );
    }
     
    int main()
    {
        queue<int*> q;
        clear(q);
        queue<void*> q2;
        clear(q2);
        return 0;
    }
    et ça compile sans problème.
    Soit j'ai loupé quelque chose, soit ça vient d'autre part dans ton code IMO.

  5. #5
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut
    Hum...moi sans l'utiliser ça compile, mais en utilisant clear(q) sur la queue<void*> j'obtiens :
    error LNK2001: unresolved external symbol "void __cdecl clear(class std::queue<void *,class std::deque<void *,class std::allocator<void *> > > &)" (?clear@@YAXAAV?$queue@PAXV?$deque@PAXV?$allocator@PAX@std@@@std@@@std@@@Z)
    et sur la queue<MaClass*> :
    error C2664: 'clear' : cannot convert parameter 1 from 'class std::queue<class Parameter *,class std::deque<class Parameter *,cl
    ass std::allocator<class Parameter *> > >' to 'class std::queue<void *,class std::deque<void *,class std::allocator<void *> > > &'
    A reference that is not to 'const' cannot be bound to a non-lvalue
    Error executing cl.exe.

  6. #6
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    Fais voir le portion de code concernée, doit y avoir un truc qui coince, aucune raison que ça marche chez moi et pas chez toi

  7. #7
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Salut,
    Le problème de link ne serait-il pas du à ce que la définition de la fonction template est dans un module cpp à part (cf. FAQ)?
    Les erreurs que tu présentes laissent à penser que ton utilisation n'est pas aussi triviale que le code que tu présentes. Peux-tu proposer le code exact qui te pose problème ?

  8. #8
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Par défaut
    Pourquoi ne pas poper tant que ce nest pas vide ?
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  9. #9
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Davidbrcz Voir le message
    Pourquoi ne pas poper tant que ce nest pas vide ?
    C'est comme pour un vector. Quand tu supprimes un élément, tu es sûr que le destructeur est appelé, en revanche, l'espace mémoire n'est pas forcément libéré. Avec cette méthode, tu obliges à libérer le conteneur précédent puisqu'avec le swap il change vers une variable de portée locale détruite en sortie de fonction.

  10. #10
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut
    voici le code exact que j'ai remodelé pour en faire un test simple et qui donne la même erreur :

    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
     
    #include <iostream>
    #include <queue>
     
    class Parameter 
    {
    public:
    	Parameter();
    	Parameter(void* value, std::string ptrType);
     
    	void* getValue();
    	std::string getPtrType();
     
    private:
    	void* m_value;
    	std::string m_ptrType;
    };
     
    Parameter::Parameter()
    {
    }
     
    Parameter::Parameter(void* value, std::string ptrType)	
    	: m_value(value), m_ptrType(ptrType)
    {	
    }
     
    void* Parameter::getValue()
    {
    	return m_value;
    }
     
    std::string Parameter::getPtrType()
    {
    	return m_ptrType;
    }
     
    template <typename T> void clear(std::queue<T*> &q);
     
    static std::queue<Parameter*> qtWidgetParametersQueue2;
     
    int main(int argc, char* argv[])
    {
    	printf("begin treatment\n");
     
    	qtWidgetParametersQueue2.push(new Parameter(reinterpret_cast<void*> (new char*("Toto OnFire")), "String"));
     
    	clear(qtWidgetParametersQueue2);
     
    	printf("end treatment\n");
     
    	return 0;
    }
     
    template <typename T> 
    	void clear(std::queue<T*> &q)
    {
    	std::queue< T * > empty;
    	std::swap( q, empty );
    }
    Erreur :

    --------------------Configuration: testQueue - Win32 Debug--------------------
    Compiling...
    testQueue.cpp(52) : fatal error C1001: INTERNAL COMPILER ERROR
    (compiler file 'msc1.cpp', line 1786)
    Please choose the Technical Support command on the Visual C++
    Help menu, or open the Technical Support help file for more information
    Error executing cl.exe.
    testQueue.exe - 1 error(s), 0 warning(s)
    L'erreur proviendrait elle du compilateur Visual C++ 6.0 ?


    PS : Je swap un truc static ! n'est ce pas là l'erreur ???

  11. #11
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par gassi64 Voir le message
    L'erreur proviendrait elle du compilateur Visual C++ 6.0 ?
    Il y a des chances
    Pourquoi ne pas utiliser un compilo plus récent (Visual express ou MinGW si tu es sous windows) ?

    [EDIT] : ton code compile sans (presque) aucun problème avec Visual Express et avec MinGW chez moi. Seul printf n'est pas reconnu sans l'en-tête adéquat (mais pourquoi ne pas utiliser std::cout dans du code C++ ? ) et un warning sur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Parameter(reinterpret_cast<void*> (new char*("Toto OnFire")), "String")

  12. #12
    Membre expérimenté Avatar de Dalini71
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2008
    Messages
    181
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2008
    Messages : 181
    Par défaut
    C'est comme pour un vector. Quand tu supprimes un élément, tu es sûr que le destructeur est appelé, en revanche, l'espace mémoire n'est pas forcément libéré. Avec cette méthode, tu obliges à libérer le conteneur précédent puisqu'avec le swap il change vers une variable de portée locale détruite en sortie de fonction.
    Ca veut dire que pour vider un vector on devrait également utiliser cette méthode ?
    myVector.clear() ou myVector.eraze(begin, end) ne suffisent pas ?

    Sinon, c'est normal que std::queue ne possède pas une méthode permettant de libérer la mémoire ?

  13. #13
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Dalini71 Voir le message
    Ca veut dire que pour vider un vector on devrait également utiliser cette méthode ?
    myVector.clear() ou myVector.eraze(begin, end) ne suffisent pas ?
    Tout dépend du contexte. Si tu vides un vecteur pour le remplir ensuite, alors autant garder le bénéfice de la mémoire déjà allouée. Si en revanche tu veux gérer au plus près la mémoire utilisée, alors oui, ça peut être une solution.
    [EDIT] clear/erase te garantissent que les destructeurs des éléments sont appelés mais pas forcément que la mémoire où sont effectivement les éléments est supprimée. Ca optimise les allocations/libérations

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Pour le vector il y'a le swap trick...
    std::vector<T>(someVector).swap(someVector);

    Enfin dans la plus part des cas c'est pas intéressant de le faire, si il libère pas lui même y'a une raison, question d'optimisation comme l'a dit 3Darchi

  15. #15
    Membre éclairé Avatar de gassi64
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2008
    Messages
    255
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Juin 2008
    Messages : 255
    Par défaut
    J'ai testé le code sur QtCreator...ça marche bien (donc avec MinGW)
    ...

    Je vais changer mon programme pour ne plus utiliser de template...puis quand le chef se décidera pour le dernier visual on sort le champagne

    Merci à tous

  16. #16
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par Goten Voir le message
    Pour le vector il y'a le swap trick...
    Effectivement. C'est en gros la fonction proposée au début de la discussion.

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

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Oui mais je répondais à Dalini dans le cas spécifique du vector qui possède une fonction membre swap.

    Par rapport au PO : visual c++ 6.0 est vraiment vieux et deprecated. C'est pas étonnant qu'il est du mal .

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

Discussions similaires

  1. Réponses: 52
    Dernier message: 23/10/2014, 11h22
  2. std::bind sur une fonction d'une classe de base template
    Par Iradrille dans le forum Langage
    Réponses: 2
    Dernier message: 30/08/2013, 17h03
  3. Généricité des Input Arguments dans une fonction
    Par RaphTIM dans le forum MATLAB
    Réponses: 5
    Dernier message: 06/06/2007, 16h28
  4. Afficher des pixels pour dessiner une fonction
    Par Sandro Munda dans le forum Linux
    Réponses: 7
    Dernier message: 13/05/2007, 11h58
  5. Pointeur sur une fonction template
    Par Progs dans le forum Langage
    Réponses: 2
    Dernier message: 15/02/2006, 20h25

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