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
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

Poser une question


"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
}
}
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.
Ce qu'on pourrait considérer un défaut de conception dans la
STL. Bien que...
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
excuse-moi, je ne vois pas de différence avec un foncteur...la fonction
"définit" le type de map
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
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 coupé des orties fraîches récemment, tu en veux ? :D
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