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 :

Conversion impossible std::pair


Sujet :

Langage C++

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 12
    Points
    12
    Par défaut Conversion impossible std::pair
    Bonjour,

    Voici mon problème :

    Mon compilateur me dit qu'il n'arrive pas a convertir mon type class quand j'essaye d'ajouter un élément à ma map :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    error C2664: 'std::pair<_Ty1,_Ty2>::pair<std::string&,maClass(void)>(_Other1,_Other2 (__cdecl &&))' : cannot convert parameter 2 from 'maClass(__cdecl *)(void)' to 'maClass(__cdecl &&)(void)'
    Le code ressemble seulement à ceci et je ne vois pas où est l'erreur.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    std::map<std::string, maClass> classList;
     
    void AddClass(std::string _name)
    {
    	maClass temp();
    	classList.insert(std::pair<std::string, maClass>(_name,temp)); 
    }
    Merci d'avance à tous

  2. #2
    En attente de confirmation mail

    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 : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Bonjour,

    La réponse est dans la FaQ : http://cpp.developpez.com/faq/cpp/?p..._list_list_fct

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 11
    Points : 12
    Points
    12
    Par défaut
    Merci

  4. #4
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Tu créés un objet std::pair que tu veux insérer (insert prend en paramètre une référence constante de ton objet) dans ta classList, mais l'objet sera détruit à la sortie de ta fonction AddClass.

    Essaie ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    std::map<std::string, maClass*> classMap;
     
    void Add(const string name)
    {
        //non exception-safe
        classMap[name] = new maClass();
        // OU
        //exception-safe (out of range)
        classMap.at(name) = new maClass();
     
        //dans les deux cas, la map sera responsable de la durée de vie de ton objet nouvellement créé. Il ne sera pas détruit à la sortie de cette fonction.
    }

  5. #5
    En attente de confirmation mail

    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 : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    @Kaamui: Comme dans tout les conteneurs, ce sont des copies qui sont insérées (déplacées si ce sont des temporaires en C++11).

    Utiliser l'allocation dynamique pour mettre des éléments dans des conteneurs demande de gérer la durée de vie des objets, typiquement avec des pointeurs intelligents. Rien n'est automatique comme tu l'entends.

    Quand à la différence [] / at elle concerne bien l'exception que tu nommes, mais ça n'a rien à voir avec l'idée d'exception safety.

  6. #6
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Comme j'ai vu dans les paramètres de la méthode insert une référence constante sur le value_type, ça me parait étrange ce que tu dis.

    Ce que j'entendais, c'est qu'à la destruction de la map, les destructeurs des objets contenus serait appelé, alors avec des pointeurs (c'est pour ça que j'utilisais new (pas spécialement pour faire une allocation dynamique).

    Par contre exception-safety, je croyais que c'était cela justement : une méthode est exception-safe quand les exceptions déclenchables sont gérées ? Qu'est-ce que c'est finalement ?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    La différence entre [] et at() ne concerne pas l'exception-safety mais la vérification de bornes (bounds-checking): Utiliser at() permet d'avoir la vérification de bornes, mais c'est à toi de rendre ton code exception-safe en plus de cela.

  8. #8
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    J'aurais du écrire un truc comme ça ?

    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
     
    void Add(const string name)
    {
        //non exception-safe
        classMap[name] = new maClass();
        // OU
        //exception-safe (out of range)
        try
        {
           classMap.at(name) = new maClass();
        }
        catch()
       {
         throw blablabla; // ?  
        }
     
        //dans les deux cas, la map sera responsable de la durée de vie de ton objet nouvellement créé. Il ne sera pas détruit à la sortie de cette fonction.
    }

  9. #9
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    L'exception-safety ce n'est pas seulement catcher les exceptions, c'est s'assurer que les objets manipulés seront toujours dans un état cohérent et qu'il n'y aura pas de fuite de mémoire.

    Ici, si le at() pète, ton new maClass() sera leaké.

  10. #10
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Et comment tu évites ça du coup ?? Sur cet exemple, à quoi ressemble un code exception-safe ?

  11. #11
    En attente de confirmation mail

    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 : 34
    Localisation : France, Doubs (Franche Comté)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 1 391
    Points : 3 311
    Points
    3 311
    Par défaut
    Tu ne peux pas savoir ce que fait une fonction simplement avec sa signature, c'est là qu'interviennent les cours, documentations et références.

    Oui, les destructeurs seront appelés à la destruction. Et donc si tu stockes des pointeurs, il te faut les détruire. C'est là qu'interviennent les pointeurs intelligents.

    Non, on distingue plusieurs niveau de résistance aux exceptions pour une fonction :
    1. Le plus faible : si une exception se déclenche, alors l'état du programme peut devenir invalide. C'est très génant, car dans ce cas même si l'on connait l'exception, il n'est pas forcément évident de retrouver un état valide.
    2. Le deuxième niveau : si une exception se déclenche, alors l'état du programme reste valide, mais peut être quelconque. On a un peu améliorer les choses, cependant il reste un problème, est ce qu'on pourra récupérer le déroulement normal du programme depuis cet état et l'exception ?
    3. Le plus fort : si une exception lance, alors l'état du programme ne change pas. C'est le plus confortable, dans ce cas tu sais où tu es en cas d'exception et celle-ci te servira à déterminer le chemin à prendre pour rejoindre le déroulement normal du programme.

  12. #12
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Je dirais un truc du genre:
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void Add(const string name)
    {
    	{
    		ptrIntelligent<MaClass> spNew = new MaClass();
    		classMap.at(name) = spNew.get();
    		spNew.detach();
    	}
    	//La suite...
    }
    Si ça pète au at(), spNew.detach() ne sera jamais appelé, donc son destructeur fera un delete sur l'objet pointé.

    Et encore, ce code date d'avant C++11 et les move semantics...

  13. #13
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Génial. Vous êtes trop forts. Donc c'est mon raw pointer qui vous défrisait ? A cause de son côté "non-owning pointer" ?

  14. #14
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 381
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 381
    Points : 41 582
    Points
    41 582
    Par défaut
    Pas le Raw Pointer en particulier, seulement la fuite de mémoire.
    Tu aurais pu t'en sortir avec un raw pointer aussi:
    Code C++ : 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
    void Add(const string name)
    {
    	maClass *rawPtr = nullptr;
    	try
    	{
    		rawPtr = new maClass();
    		classMap.at(name) = rawPtr;
    		rawPtr = nullptr;
    	}
    	catch()
    	{
    		if(rawPtr != nullptr)
    			delete rawPtr;
    		throw blablabla; // ?  
    	}
    }
    C'est juste plus compliqué.

  15. #15
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    La fuite mémoire potentielle avec l'utilisation de at ?

  16. #16
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Génial. Vous êtes trop forts. Donc c'est mon raw pointer qui vous défrisait ? A cause de son côté "non-owning pointer" ?
    Tu peux utiliser des pointeurs nus, mais ils ne seront pas du tout automatiquement libérés avec la map.

    la map sera responsable de la durée de vie de ton objet nouvellement créé.
    C'est cette affirmation qui est fausse, en tous cas en partie.
    La libération de chaque élément de la map devra être faite par l'utilisateur et ne sera en aucun cas faîte par la map elle-même.

    A la destruction d'un vector<T>, c'est T::~T() qui est appelé sur chaque élément.
    Si T est un pointeur, il ne s'agira en aucun cas d'un appel à un delete de la mémoire pointée, mais toujours à ~T().

  17. #17
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Novembre 2011
    Messages
    685
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2011
    Messages : 685
    Points : 1 418
    Points
    1 418
    Par défaut
    Oui oui j'avais déjà compris que j'avais dis une connerie à ce niveau là. L'objet est détruit, pas le pointeur que j'ai créé en même temps que l'objet (c'est pas de ma faute je suis fatigué )

  18. #18
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 128
    Points : 33 053
    Points
    33 053
    Billets dans le blog
    4
    Par défaut
    Citation Envoyé par Kaamui Voir le message
    Oui oui j'avais déjà compris que j'avais dis une connerie à ce niveau là. L'objet est détruit, pas le pointeur que j'ai créé en même temps que l'objet (c'est pas de ma faute je suis fatigué )
    Après on est dans le chipotage grammatical, mais perso je dirais plutôt que le pointeur est détruit, pas l'objet (pointé).

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

Discussions similaires

  1. Défénir un std::map à partir d'un std::pair
    Par mat087 dans le forum SL & STL
    Réponses: 3
    Dernier message: 30/12/2006, 19h36
  2. tri sur std::vector<std::pair<int, float> >
    Par b4u dans le forum SL & STL
    Réponses: 15
    Dernier message: 01/10/2006, 09h19
  3. Equivalent de std::pair mais pour trois valeurs
    Par Rodrigue dans le forum SL & STL
    Réponses: 6
    Dernier message: 26/09/2006, 22h00
  4. Conversion de std::string en LPCWSTR
    Par Rodrigue dans le forum SL & STL
    Réponses: 11
    Dernier message: 16/05/2006, 15h33
  5. (Problème avec...) conversion de std::string en char
    Par crossbowman dans le forum SL & STL
    Réponses: 7
    Dernier message: 05/03/2006, 19h54

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