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 :

multimap et equal_range


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Points : 121
    Points
    121
    Par défaut multimap et equal_range
    Bonsoir,

    J'ai une multimap de type :
    pour faire un médiateur.

    A étant une classe de base virtuelle ayant notamment une donnée membre qui me permet d'établir une relation d'ordre.
    Soient B, C des classes filles.

    J'ai donc défini un operator < ( qui s'appuie sur le nom name) et tout marche bien quand je veux récupérer une clef précise.


    Seulement voilà, je voudrai savoir s'il y a moyen d'utiliser un equal_range qui ne s'appuie pas sur cet opérateur < qui me permettrait par exemple d'afficher que les objets de type B*.


    J'aimerai donc éviter du code comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    typedef multimap<A*,A*> listA;
    typedef listA :: const_iterator MIT;
     
    for (MIT mit = listA.begin(); mit != listA.end(); ++mit) {
              const pair<const A*,const A*> p = *mit; 
              if (dynamic_cast<const B*>(p.first))  p.second->display(); // ParEx
              };
     
    // Un peu embêtant quand il n'y a que 3 ou 4 objets concernés sur 150 :((
    et avoir plutôt :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    pair<MIT,MIT> p = listA.equal_range(/* objet foncteur approprié? */);
    for (MIT mit=p.first;mit!=p.second;++mit) mit->second->display();
    J'ai bien pensé à une solution genre :
    - Oh ben suffit de faire commencer les noms de la classe A par "A" etc... mais bon c'est pas très fiable ... et je suis sûr qu'il y a une façon propre et efficace .

  2. #2
    Expert éminent sénior
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 275
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 275
    Points : 10 985
    Points
    10 985
    Par défaut
    J'imagine que tu avais oublié de préciser la fonction de comparaison dans la définition de ta table.
    Sinon, comme ça au hasard (j'ai lu en diagonale, je l'avoue), boost.multi_index peut-être ?
    Sinon, recopier tes données (des pointeurs ici) dans un set trié suivant ton autre critère -- ou faire une copie à plat dans un vecteur et appliquer un std::sort par dessus -- si tant est qu'il n'existe pas une fonction qui permettra de trier le strict minnimum pour extraire exactement ce qui t'interresse.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Yvelines (Île de France)

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

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Points : 16 213
    Points
    16 213
    Par défaut
    L'efficacité d'equal_range vient du fait qu'il travaille sur une collection triée. Or si tu as déjà choisi de trier ta map autrement, tant pis, tu n'as qu'un ordre de tri par map.

    Quelques pistes, au hasard :

    - Stocker les résultats de ton algorithme lourd dans un vector<map<A*, A*>::iterator> pour avoir les résultats en mémoire le coup d'après
    - Utiliser un conteneur avec plusieurs ordres de classement possible, comme bost::multi-index.
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2005
    Messages : 109
    Points : 121
    Points
    121
    Par défaut
    Oui absolument, c'était pour simplifier mon post.

    J'ai défini ceci :

    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
     
    // C'est cette structure qui va me servir de comparaison
    struct CompareA{
            bool operator() (const A*,const A*) const;
            };
     
     
     class A {
     private :
         string name;
    /*...*/
     
     public :
    /*...*/
     string getName() const           { return name; }
     
    // Les classes B et C ont aussi cet opérator < de défini
     template <typename T> bool operator <  (const T& a) const  { return getName() < a.getName(); }
     };
     
    inline bool CompareA :: operator()(const A* a,const A* b) const    { return *a<*b; }
    et ma map devient :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    multimap<A*,A*,CompareA> listA
    Merci à vous deux, je vais essayer de voir du côté de boost.

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

Discussions similaires

  1. [C++] Multimap with ostream_iterator
    Par taron dans le forum SL & STL
    Réponses: 2
    Dernier message: 16/01/2006, 13h24
  2. Question sur les multimaps
    Par Chii-san dans le forum SL & STL
    Réponses: 4
    Dernier message: 08/11/2005, 09h08
  3. STL : utilisation d'une multimap
    Par romeo9423 dans le forum SL & STL
    Réponses: 7
    Dernier message: 18/08/2005, 07h56
  4. multimap initialisation
    Par moldavi dans le forum C++
    Réponses: 2
    Dernier message: 14/03/2005, 17h04
  5. mais que fait upper_range() dans un multimap?
    Par porcher dans le forum C++
    Réponses: 7
    Dernier message: 18/02/2005, 22h21

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