GNT sans publicité, site mobile, fonctionnalitées exclusives...

problème de parcours de map

Le
MGN
Bonsoir,
J'ai des map du type
std::map<objet*,objet*,foncteur>
où le foncteur varie (le type des objets aussi, mais ça ne change rien à la
définition de la map).
Je cherche à parcourir (uniquement parcourir, pas modifier) une map de ce
type sans connaître le foncteur qui a été utilisé pour le tri, ie quelque
chose du type :

std::map<objet*,objet*,foncteur> x;
std::map<objet*,objet*>::iterator it;
for(it=x.begin();it!=x.end();++it) {}

Evidement, cette syntaxe ne marche pas. Quelqu'un sait comment faire ?
Merci à vous
Marc
Lire les 24 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 5
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Fabien LE LEZ
Le #20107511
On Thu, 10 Sep 2009 00:50:32 +0200, "MGN"
J'ai des map du type
std::map<objet*,objet*,foncteur>
où le foncteur varie



"std::map <T, T, machin>" et "std::map <T, T, truc>" sont deux types
différents, tout comme "std::string" et "int" sont deux types
différents.

Si tu veux une fonction qui accepte en paramètre plusieurs types
différents, il te faut un template :

template <class Map> void f (Map const& m)
{
for (Map::const_iterator i= m.begin(); i != m.end(); ++i)
{
// faire quelque chose
}
}

Si tu veux t'assurer que seul un std::map<objet*,objet*,?> sera
accepté par la fonction :

template <class Foncteur> void f
(std::map<objet*,objet*,Foncteur> const& m)
{
for (Map::const_iterator i= m.begin(); i != m.end(); ++i)
{
// faire quelque chose
}
}
Fabien LE LEZ
Le #20107501
J'ai écrit :

template <class Foncteur> void f
(std::map<objet*,objet*,Foncteur> const& m)



Pour des raisons de cohérence, il vaut peut-être mieux remplacer
"Foncteur" par "Compare" ici. Mais bon, ça ne change rien au
fonctionnement du code.
James Kanze
Le #20109051
On Sep 10, 1:04 am, Fabien LE LEZ
On Thu, 10 Sep 2009 00:50:32 +0200, "MGN"


>J'ai des map du type
>std::map<objet*,objet*,foncteur>
>où le foncteur varie



"std::map <T, T, machin>" et "std::map <T, T, truc>" sont deux
types différents, tout comme "std::string" et "int" sont deux
types différents.



Ce qu'on pourrait considérer un défaut de conception dans la
STL. Bien que...

Si tu veux une fonction qui accepte en paramètre plusieurs
types différents, il te faut un template :



template <class Map> void f (Map const& m)
{
for (Map::const_iterator i= m.begin(); i != m.end(); ++i)
{
// faire quelque chose
}
}



Si tu veux t'assurer que seul un std::map<objet*,objet*,?>
sera accepté par la fonction :



template <class Foncteur> void f
(std::map<objet*,objet*,Foncteur> const& m)
{
for (Map::const_iterator i= m.begin(); i != m.end(); ++i)
{
// faire quelque chose
}
}



Ce qui manque de souplesse. Si ça suffit à MGN, bien ; c'est
certainement la solution la plus simple. Mais ça signifie qu'à
un endroit donné dans le code, c'est toujours le même type de
map qui sert (et que le compilateur sache ce type) . Sinon,
c'est tout à fait possible de faire des maps avec des
comparateurs différents, mais avec le même type. À la place d'un
objet fonctionnel pour le comparateur, il suffit d'utiliser une
fonction :
typedef std::map< Object*, Object*, bool cmp( Object*, Object* ) >
Map ;
Du coup, on spécifie le comparateur lors de la construction, et
tous les map ont le même type. (On pourrait aussi utiliser un
objet fonctionnel unique qui se sert du modèle lettre/enveloppe
pour le polymorphisme, mais c'est plus compliqué.)

--
James Kanze
MGN
Le #20109231
> À la place d'un
objet fonctionnel pour le comparateur, il suffit d'utiliser une
fonction :
typedef std::map< Object*, Object*, bool cmp( Object*, Object* ) >
Map ;
Du coup, on spécifie le comparateur lors de la construction, et
tous les map ont le même type.



excuse-moi, je ne vois pas de différence avec un foncteur...la fonction
"définit" le type de map

(On pourrait aussi utiliser un
objet fonctionnel unique qui se sert du modèle lettre/enveloppe
pour le polymorphisme, mais c'est plus compliqué.)



oui, j'avais pensé à cette solution, mais j'ai peur de diminuer les
performances...

=> j'ai une solution qui va faire hurler :-())
je fais un reinterpret_cast de std::map<objet*,objet*,foncteur> en
std::map<objet*,objet*> et je parcours la map castée avec un
std::map Tant que je n'utilise l'iterateur qu'à des fins de visualisation, ie sans
modifier la map, il n'y a aucun risque....
Qu'en pensez-vous ?
(j'ajoute qu'il n'y a que 3 lignes de code concernées et que la performance
est importante)
Merci
Marc
Mickaël Wolff
Le #20109871
MGN a écrit :

excuse-moi, je ne vois pas de différence avec un foncteur...la fonction
"définit" le type de map


La différence c'est que le foncteur est un objet, alors que James te
proposes de ne fournir qu'un pointeur sur une fonction. Du coup, même si
tu changes la fonction, le type de map sera le même.

=> j'ai une solution qui va faire hurler :-())
je fais un reinterpret_cast de std::map<objet*,objet*,foncteur> en
std::map<objet*,objet*> et je parcours la map castée avec un
std::map

J'ai coupé des orties fraîches récemment, tu en veux ? :D

Tant que je n'utilise l'iterateur qu'à des fins de visualisation, ie
sans modifier la map, il n'y a aucun risque....
Qu'en pensez-vous ?
(j'ajoute qu'il n'y a que 3 lignes de code concernées et que la
performance est importante)



Pourquoi ne fais-tu pas un typedef comme James le proposes ?

typedef std::map<objet*,objet*,foncteur> Map ;
Map x;
for(Map::iterator it = x.begin() ; it != x.end() ; ++it) {}

--
Mickaël Wolff aka Lupus Michaelis
http://lupusmic.org
Publicité
Suivre les réponses
Poster une réponse
Anonyme