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

C++ Discussion :

insertion dans une MAP


Sujet :

C++

  1. #1
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2012
    Messages : 56
    Par défaut insertion dans une MAP
    Bonjour à tous,

    je rencontre des problèmes pour insérer des données avec un it.first déjà existant dans une map. J'ai essayé de synthétiser et simplifier au maximum le besoin.

    Exemple:

    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
    #pragma once
     
    #include <string>
    #include <vector>
    #include <map>
     
    struct example
    {
    	int id;
    	std::string name;
    };
     
    struct data
    {
    	int number;
    	std::string string;
    };
     
    class c
    {
    	private:
    	std::map<example, std::vector<data>> m;
     
    	public:
    	void add(example &ex)
    	{
    		data d;
    		bool state = false;
    		for (const auto& its : m)
    		{
    			if (its.first.id == ex.id)
    			{
    				m[its.first].push_back(d);
    				//m_.emplace(std::make_pair(its.first, d));
    				state = true;
    				break;
    			}
    		}
    		if (!state) m.emplace(std::make_pair(ex, d));
    	}
    };
    Merci bien.

  2. #2
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Quel est le problème ?
    Pourquoi ne pas simplement faire m[ex.id].push_back(d); ? L'opérateur [] de la map commence par créer la valeur si elle n'existe pas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2012
    Messages : 56
    Par défaut
    Bonjour Bousk,

    ça ne compile pas ! et les erreurs ne sont pas du tout explicites et me renvoient dans xutility et xstddef.

    Le but étant de faire un test sur un champ (id) et de stocker l'intégralité de la structure dans la map.

    En fait je ne vois rien d'anormal, je me demande si le soucis ne viendrait pas d'ailleurs.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 503
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 503
    Par défaut
    les erreurs ne sont pas du tout explicites
    Pour vous.
    Laissez-nous en juger.
    Les messages d'erreur, SVP.

  5. #5
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    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 : 5 202
    Par défaut
    pour moi, le problème pourrait bien être que tu n'as pas défini operator <, au moins dans le code que tu nous montres.

  6. #6
    Membre éprouvé
    Inscrit en
    Mai 2012
    Messages
    65
    Détails du profil
    Informations forums :
    Inscription : Mai 2012
    Messages : 65
    Par défaut
    Si tu veux stocker ta class example dans ta map, il faut que tu définise un opérateur de comparaison (à mettre en fonction libre):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    //trie sur l'id
    bool operator< (const example & e1, const example & e2)
    {
    	return e1.id < e2.id;
    }
    Et tu peux utiliser ta map comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    std::map<example, std::vector<data>> m;
    example e{1, "toto"};
     
    data d{5, "titi"};
     
    m[e].push_back(d);

  7. #7
    Membre confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    56
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Juin 2012
    Messages : 56
    Par défaut
    Bonjour,

    En effet, le problème viendrait de l'absence de la surcharge d'opérateur.

    :\program files (x86)\microsoft visual studio 14.0\vc\include\xstddef(239): error C2678: '<' binaire*: aucun opérateur trouvé qui accepte un opérande de partie gauche de type 'const Event' (ou il n'existe pas de conversion acceptable)
    1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\system_error(436): note: est peut-être 'bool std::operator <(const std::error_condition &,const std::error_condition &) noexcept'
    1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\system_error(427): note: ou 'bool std::operator <(const std::error_code &,const std::error_code &) noexcept'
    1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstddef(239): note: lors de la tentative de mise en correspondance de la liste des arguments '(const Event, const Event)'
    1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xstddef(238): note: lors de la compilation de la fonction membre '<Inconnu>' de la classe <Inconnu>
    1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xutility(812): note: voir la référence à l'instanciation de la fonction modèle 'bool std::less<_Kty>::operator ()(const _Ty &,const _Ty &) const' en cours de compilation
    Oui mais le fait de créer une fonction libre aura forcément de gros impacts sur la solution, il faut prendre en compte les effets de bords.. et ça ne compile toujours pas (erreurs de linkage).

  8. #8
    Rédacteur/Modérateur


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

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    L'erreur est plutôt claire effectivement.
    Citation Envoyé par bowow Voir le message
    Oui mais le fait de créer une fonction libre aura forcément de gros impacts sur la solution, il faut prendre en compte les effets de bords.. et ça ne compile toujours pas (erreurs de linkage).
    Gros impacts ? Effets de bord d'une fonction libre d'opérateur <, pour laquelle les paramètres sont sensés être const& ?
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  9. #9
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,
    Citation Envoyé par bowow
    Oui mais le fait de créer une fonction libre aura forcément de gros impacts sur la solution, il faut prendre en compte les effets de bords.. et ça ne compile toujours pas (erreurs de linkage).
    A vrai dire, à part le fait que n'importe quelle unité de compilation dans laquelle l'opérateur < serait défini pour example pourrait l'utiliser, je ne vois pas vraiment de quels effets de bord tu veux parler. Comme les paramètres sont -- de toutes manières -- transmis sous forme de référence constante, il n'y a aucun effet de bord à craindre

    A moins, bien sur, que tu ne parle du fait de forcer la comparaison de ta structure example sur un de ses champs bien particulier!!!

    En effet, la définition de l'opéateur < te forcerait à choisir la manière de comparer deux éléments de type example. Est-ce
    • au travers de la valeur du champs id ?
    • au travers de la valeur du champs name ?


    Et qu'il est vrai que ce choix aurait quelque chose de... définitif (comprends : identique et imposé dans toutes les unités de compilation ayant connaissance de la structure example)

    Et bien sur, le véritable problème est qu'aucune solution ne peut être considérée comme meilleure : dans certains cas, tu voudras sans doute trier tes éléments uniquement par l'id, dans d'autres (c'est surement plus facile pour l'utilisateur) tu voudras les trier par nom.

    Mais des solutions existent, entre autres, parce que -- contrairement à ce que l'on croit généralement -- std::map est une collection template s'attendant à disposer de quatre paramètres template :
    il y a les deux que "tout le monde connait" (key et value), mais le troisième paramètre nous permet de définir le comparateur (qui équivaut par défaut à less<Key> et donc à l'opérateur <), et le dernier 'allocator) paramètre nous permet de définir la politique de construction / destruction des éléments de la collection.

    Avant C++11, nous aurions pu être tenté d'utiliser des foncteurs qui auraient pu être proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct LessById{
        bool operator()(example const & a, example const & b) const{
            return a.id < b.id;
        }
    };
    struct LessByName{
        bool operator()(example const & a, example const & b) const{
            return a.name < b.name;
        }
    };
    qui nous auraient alors permis d'utiliser le "tri par le champs id" dans notre std::map sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<example, std::vector<data>, LessById> m;
    ou, au contraire, de choisir le "tri par nom" dans notre std::map sous une forme proche de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    std::map<example, std::vector<data>, LessByName> m;
    Et, dans le pire des cas, il resterait toujours possible d'envisager le recours à boost::bimap (si on souhaite vraiment avoir la possibilité de disposer des deux tris simultanément )

    Ceci dit, il faut être bien consicent du fait que -- quoi qu'il arrive -- si ces deux foncteurs (et les modifications apportée à la déclaration de la map) suffisent à permettre au code de compiler, la clé de la map reste du type... example
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. Insertion d'un élément vide dans une map.
    Par jamsgoodon dans le forum Débuter
    Réponses: 2
    Dernier message: 24/03/2011, 13h51
  2. insertion dans une map
    Par salseropom dans le forum C++
    Réponses: 5
    Dernier message: 14/09/2010, 01h39
  3. [POO] Insertion d'un template dans une map
    Par JSmey dans le forum Langage
    Réponses: 6
    Dernier message: 27/11/2008, 11h50
  4. problème avec insert dans une map
    Par LePetitBricoleur dans le forum C++
    Réponses: 3
    Dernier message: 01/11/2007, 11h52
  5. problème d'insertion de données dans une map
    Par kifouillou dans le forum Collection et Stream
    Réponses: 11
    Dernier message: 21/02/2007, 10h10

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