std::find - C++ - Programmation
Marsh Posté le 15-05-2009 à 14:31:30
A::operator==(const C& ) permet de comparer A avec C.
C'est dans C que tu dois redéfinir == pour comparer deux C ensembles.
Marsh Posté le 15-05-2009 à 14:44:40
ça serait peut-être plus facile à voir avec le code source ...
Marsh Posté le 15-05-2009 à 14:45:57
@Elmo: find est assez intelligent, pour savoir qu'il faut qu'il utilise les objets C des objets B pour comparer avec le 3eme argument de find, c'est à dire un objet de type C ?
je pensais que find comparer chaque élément contenu dans le container qu'on lui passe avec le 3eme argument, hors dans mon cas ,le 3eme arguement 'nest pas du type des deux premiers, d'où le recours à la surcharge d'un A::operator==(const C& ) dans la classe A donc, puisque le contenaire contient des A*
Marsh Posté le 15-05-2009 à 14:51:09
J'avais mal saisi ton besoin on dirait.
Marsh Posté le 15-05-2009 à 14:55:27
très bien merci pour find_if, la solution donc aurait été de rédéfinir également A::operator ==(A& ) qui appel A::operator ==(C& )
Marsh Posté le 15-05-2009 à 15:07:55
non, ce n'est pas "la" solution. A partir du moment où ton conteneur manipule des pointeurs, find se contentera d'appeler un opérateur de comparaison de pointeur. En rrègle générale, tu ne voudras pas changer le comportement de cet opérateur. La solution élégante, c'est le find_if.
Marsh Posté le 15-05-2009 à 15:16:22
oui thx
Marsh Posté le 15-05-2009 à 21:06:27
ReplyMarsh Posté le 17-05-2009 à 00:11:42
d'ailleurs c'est possible avec une structure de données comme ça :
Code :
|
de recherche une valeur à partir d'une key de type string, en utilsant std::find ??
Marsh Posté le 17-05-2009 à 18:04:14
deuxième question, comment tester le retour d'un find_if qui n'a rien touvé, je me retrouve avec un iterator non intialisé , comment gérer ça ?
Marsh Posté le 17-05-2009 à 20:17:01
Glock 17Pro a écrit : faut avouer que c'est reloud/pas élégant de créer une classe rien que pour ça |
t'es payé à la ligne de code ?
Y a rien d'inélégant dans cette solution
Marsh Posté le 18-05-2009 à 10:41:26
Glock 17Pro a écrit : deuxième question, comment tester le retour d'un find_if qui n'a rien touvé, je me retrouve avec un iterator non intialisé , comment gérer ça ? |
ca retour l'itérateur de fin, quand ca ne trouve rien
Marsh Posté le 18-05-2009 à 10:42:45
Glock 17Pro a écrit : d'ailleurs c'est possible avec une structure de données comme ça :
|
Non, faut passer par un find_if
Et garde le courage ... dans C++0x, ce sera encore plus facile à utiliser grâce aux lambdas
Marsh Posté le 18-05-2009 à 12:55:01
theshockwave a écrit : |
un seul et unique find_if, pour aller chercher une string dans un section->vector->pair ?
Marsh Posté le 18-05-2009 à 13:31:46
ben, tu vas sans doute préférer boucler sur ton tableau et faire un find_if par Section, après, si tu veux juste la première section contenant la clé et que tu te tamponnes de la valeur associée, tu peux faire un find_if sur ton tableau avec un prédicat qui refait un find_if dans ta section.
Marsh Posté le 18-05-2009 à 14:42:42
et ça reste mieux (mieux en terme de je sais pas quoi d'ailleurs, de perf sans doute) d'utiliser ce genre d'approche plutôt que de faire une recherche avec des pauvres boucle for ? car au niveau du nombre de lignes de code c'est pas la même ...
Marsh Posté le 18-05-2009 à 15:37:04
ben, à partir du moment où tu te poses la question des perfs de tes recherches, c'est peut-être que ton vector< string, string > n'était pas un bon choix, ou alors que tu devrais considérer l'idée de trier ton vector avant de chercher dedans, auquel cas, oui, il vaudrait mieux te faire une recherche dichotomique dedans que passer par un find_if.
find_if est juste là pour te simplifier la vie. Il faut voir si ton prédicat va être réutilisable, par exemple. Accessoirement, aussi, tu n'es pas obligé d'écrire une classe toi-même.
Et puis pour la lisibilité du code, ca me semble quand même être plus chouette. Un petit exemple :
Code :
|
Ca me semble largement plus joli que de faire la recherche manuellement avant l'insertion
Edit: modif des noms de variables
Marsh Posté le 18-05-2009 à 16:34:59
find_if ne fait que faire des boucles while de toutes façon.
Les perfs d'une STL proprement codé (aka non M$) est identique au pouillement prés au code générique équivalent.
Marsh Posté le 21-05-2009 à 23:29:09
En faite si on veut utiliser les algo de la stl pour recherche dans une structure de donnés comme ci-dessous, y a pas plus simple que de
faire comme ça ?
C'est censé être plus rapide que for + for ?
Code :
|
Marsh Posté le 22-05-2009 à 01:14:58
Euh, ta proposition est plutôt complexe, oui. Ta structure ValeurNulle n'a d'utilité que dans le cas où tu ne vas pas préciser l'élément recherché ... Est-ce vraiment nécessaire de permettre ca, du coup ?
D'autre part, vu que tu fais un for_each, tu es conscient que tu ne vas pas t'arrêter quand tu auras trouvé le bon élément, n'est-ce pas ?
si tu veux faire ca, je pense que tu as meilleur temps d'itérer à la main sur ton vector<A*>
du coup, ca te donne un main du type :
Code :
|
Et du coup, tu n'as plus besoin de ta structure de Finder non plus
Edit :
Si tu veux te poser des questions de perfs, tu devrais peut-être envisager d'avoir un conteneur associatif type map plutôt qu'un vecteur avec un système de clé/valeur géré à la main. Et si tu tiens à garder un vecteur, tu peux au moins t'assurer qu'il est trié auquel cas, tu préfèreras faire une recherche dichotomique par toi-même plutôt que reposer sur un find_if, évidemment ... Mais entre un find_if et une itération "bête" à la main, tu n'auras pas de différence de perf.
Marsh Posté le 22-05-2009 à 09:05:35
et là avec ce code, il va tester le premier élément contenu dans pair, ça marche juste pour un vector de string, no?
PS: oui dans mon code j'ai oublié de faire un if(test!=val) avant chaque appel à find_if, mais bon même le for_each est pas adapté là oui...
Marsh Posté le 22-05-2009 à 13:05:09
argh, il était tard et j'ai fait quelques erreurs
à la place du equal_to, il faudrait faire un truc du style :
Code :
|
modulo les autres étourderies que j'ai pu faire
Edit :
Là, oui, c'est juste adapté pour le vector< string, string >, mais bon, est-ce vraiment un problème ? Tu peux adapter ca facilement pour les autres cas, et ca ne me semble pas avoir trop de sens de faire ca en générique (enfin, à la limite, tu mettre le prédicat en template, éventuellement) et à titre de rappel, en C++0x, la recherche sera encore plus simple :
Code :
|
Donc attention à ne pas faire une uzine à gaz qui sera remplacée prochainement par un truc simple
Marsh Posté le 15-05-2009 à 14:11:50
soit:
- une classe B héritant d'une classe abstraite A
- un vecteur de A* instancié comme étant des objets B
- une classe C, membre donné de B
je veux utiliser std::find sur le vecteur de A* en comparant les objets C de chaque A* avec une variable de type C.
Si je redéfinis un opérateur == virtual pur dans A puis l'implémente dans B
bool operator ==(const C& ){....}
ça ne marche pas, le compilo me sort
binary '==' : no operator found which takes a right-hand operand of type 'const C' (or there is no acceptable conversion)
Quelqu'un voit le problème ?
---------------
je connais tout, je ne sais rien, seule certitude, à vouloir trop on finit par tout perdre.