Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1738 connectés 

  FORUM HardWare.fr
  Programmation
  C++

  [C++/STL] Retrait d'un élément dans une list

 


 Mot :   Pseudo :  
 
 Page :   1  2
Page Précédente
Auteur Sujet :

[C++/STL] Retrait d'un élément dans une list

n°609416
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 21:29:13  profilanswer
 

Le code suivant me pond une exception...
 

Code :
  1. list < Cmachin > Cmachin_list;


 

Code :
  1. for ( it = Cmachin_list.begin() ; it != Cmachin_list.end() ; ++it)
  2. {
  3.    if( qqchose_de_vrai )
  4.       Cmachin_list.erase(it);
  5. }


 
La boucle n'est peut etre pas la meilleure structure de contrôle pour réaliser le retrait d'un élément d'une liste. :non:  
 
Comment puis-je m'en sortir de manière plaisante ?
 
Merci d'avance,
   Xterm-in-hate.

mood
Publicité
Posté le 12-01-2004 à 21:29:13  profilanswer
 

n°609432
Taz
bisounours-codeur
Posté le 12-01-2004 à 21:37:14  profilanswer
 

rtfm
 
void remove(const T& val);
 
template<class Predicate>  
void remove_if(Predicate p);  
[4]

n°609491
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 21:52:35  profilanswer
 

Merci taz, mais j'ai pas encore décoder la totalité de ce que tu as écrit :)
 
D'aitre part, ci-joint l'aide dans la MSDN :
 
list::erase
iterator erase(iterator it);
iterator erase(iterator first, iterator last);
The first member function removes the element of the controlled sequence pointed to by it. The second member function removes the elements of the controlled sequence in the range [first, last). Both return an iterator that designates the first element remaining beyond any elements removed, or end() if no such element exists.
 
Erasing N elements causes N destructor calls. No reallocation occurs, so iterators and references become invalid only for the erased elements.
 
PAr conséquent, j'ai modifié mon code de la sorte :
 

Code :
  1. for ( it = Cmachin_list.begin() ; it != Cmachin_list.end() ; ++it)
  2. {
  3.   if( qqchose_de_vrai )
  4.      it = Cmachin_list.erase(it);  // erase() retourne le nouvel it valide (si j'ai bien capté)
  5. }

 
 
Je n'ai plus d'exception mais je ne suis pas sur que cela marche parfaitement...
 
Cordialement,
   Xterm-in-hate.

n°609496
Taz
bisounours-codeur
Posté le 12-01-2004 à 21:53:21  profilanswer
 

putain mais lit pas la msdn pour STL
 
tu vas sur le site de SGI comme tout le monde :o

n°609503
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 21:55:15  profilanswer
 

Ca doit être mon profil "programmeur de fortran des années 50"... je suis pas encore tres familiarisé avec STL ;)
 
Xter.

n°609536
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 22:04:33  profilanswer
 

Mon code est sans doute foireux.
 
Erase() retourne un iterator valide qui suit l'element retiré de la liste. Puis, dans ma boucle for(), j'incremente l'iterator d'un élement.
 
Donc l'element de la liste qui suit l'élément retiré est systématiquement sauté... ca plante pas mais c est pas correct.
 
Cordialement,
   Xter.

n°609545
Taz
bisounours-codeur
Posté le 12-01-2004 à 22:08:47  profilanswer
 

mais tu le fais exprès ou t'es capable de consulter la documentation de sgi et celle des fonctions membres remove et remove_if ?

n°609577
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 22:18:13  profilanswer
 

Je suis un peu sourd, tu fais bien d'insister !
 
Effectivement remove_if correspond exactement à ce que je recherche :) Par contre la syntaxe du Predicate ne m'est pas familière mais je devrais y arriver...
 
Merci,
   Xter.

n°609599
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 22:26:49  profilanswer
 

Je dirais même plus, elle est rudement balaise la syntaxe ! Ca me tue...

n°609602
Taz
bisounours-codeur
Posté le 12-01-2004 à 22:30:25  profilanswer
 

tu comprends quoi ?

mood
Publicité
Posté le 12-01-2004 à 22:30:25  profilanswer
 

n°609605
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 22:36:19  profilanswer
 

Comment puis-je faire pour transformer l'ecriture de ma condition if( qqchose) en un Predicate ?
 
Si tu as des exemples parlants des fonctions en XXXX_if(,, Predicate p ). Il semblerait qu'elles soient couplées avec l'appel de Bind1st ou Bind2nd ....
 
 
 

n°609610
Taz
bisounours-codeur
Posté le 12-01-2004 à 22:38:40  profilanswer
 

template<class Predicate>  
void remove_if(Predicate p);
->
Removes all elements *i such that p(*i) is true.

n°609612
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 22:38:44  profilanswer
 

Oui, merci.
 
Predicate pourrait être une fonction qui retourne un BOOL... lol


Message édité par xterminhate le 12-01-2004 à 22:39:29
n°609634
Taz
bisounours-codeur
Posté le 12-01-2004 à 22:51:11  profilanswer
 

pas BOOL, mais bool. et Predicate p est template et peut être n'importe quoi qui a un opérateur operator()(const T & ) const
 
donc fonction ou objet

n°609774
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 23:23:32  profilanswer
 

La fonction remove_if( start, end, predicate p) fonctionne parfaitement avec en argument une simple fonction qui retourne bool.
 
Par contre list.remove_if( predicate p) fonctionne differement et j'arrive à rien.
 
Dans Visual :
'remove_if' : cannot convert parameter 1 from 'bool (struct x_ClientSocket)' to 'class std::binder2nd<struct std::not_equal_to<struct x_ClientSocket> >'
 


Message édité par xterminhate le 12-01-2004 à 23:27:40
n°609817
Taz
bisounours-codeur
Posté le 12-01-2004 à 23:47:56  profilanswer
 

donne du code

n°609826
xterminhat​e
Si vis pacem, para bellum.
Posté le 12-01-2004 à 23:58:55  profilanswer
 

Tout se déroule dans une classe nommée X_HttpServer.
 
La liste:

Code :
  1. typedef list< x_ClientSocket > x_ClientSocketList;
  2. x_ClientSocketList client_socket_list;


 
L'appel de std::list.remove_if() à partir d'une fonction membre de x_HttpServer:

Code :
  1. // Disconnect and remove client socket element
  2. client_socket_list.remove_if( ClientSocketDisconnectionTest );


 
La fonction membre de x_HttpServer qui réalise le test de l'élement de la liste a retirer :

Code :
  1. bool x_HttpServer::ClientSocketDisconnectionTest(x_ClientSocket cs)
  2. {
  3. // Local varaibles
  4. long current_time;
  5. // Obtain current time
  6. time( &current_time );
  7. // Return true if client socket must be disconnected
  8. return( ( ( !cs.bKeepAlive ) && ( ( current_time - cs.lLastRequestTime ) > cFirstRequestTimeOut ) ) ||
  9.      ( ( cs.bKeepAlive ) && ( ( current_time - cs.lLastRequestTime ) > cNextRequestTimeOut ) ) ||
  10.      cs.bForceDisconnection );
  11. }


 

n°609852
Taz
bisounours-codeur
Posté le 13-01-2004 à 00:42:18  profilanswer
 

et elle à la tronche de ce qui est demandé ? non
c'est même pas synthaxiquement correct ton truc

n°609863
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 00:47:33  profilanswer
 

Oui je sais bien, mais je suis incapable de coder une fonction qui ait le format demandé ! Pour le moment... moi et STL c'est pas encore cà et j'apprends de manière empirique !
 
Pourtant,
 

Code :
  1. remove_if( client_socket_list.begin(), client_socket_list.end(), ClientSocketDisconnectionTEst );


 
fonctionne parfaitement. Mais ca ne modifie pas ma liste... evidemment !


Message édité par xterminhate le 13-01-2004 à 00:48:59
n°609882
verdoux
And I'm still waiting
Posté le 13-01-2004 à 00:54:30  profilanswer
 

Ben non y a pas de erase.
Mais bon pour les listes c'est plutôt
client_socket_list.remove_if(ClientSocketDisconnectionTEst );

n°609902
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 00:59:52  profilanswer
 

Exact mais encore faut il fournir à cette #?&! de fonction remove_if le bon argument à la sauce STL.

n°609912
Taz
bisounours-codeur
Posté le 13-01-2004 à 01:09:12  profilanswer
 

xterminhate a écrit :

Exact mais encore faut il fournir à cette #?&! de fonction remove_if le bon argument à la sauce STL.  

1) c'est pas le bon type
2) je sais pas ou t'as vu qu'on se servait d'un pointeur de fonction membre comme ça
3) voir mes premiers messages

n°610111
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 08:09:22  profilanswer
 

SGI a dit :
 
Remove_if returns an iterator that points to the end of the resulting range after elements have been removed from it; it follows that the elements after that iterator are of no interest, and may be discarded. If you are removing elements from a Sequence, you may simply erase them. That is, a reasonable way of removing elements from a Sequence is ...

Code :
  1. S.erase(remove_if(S.begin(), S.end(), pred), S.end()).


 
Interessant ! Donc voici mon code et cela semble marcher correctement :
 

Code :
  1. client_socket_list.erase(remove_if( client_socket_list.begin() , client_socket_list.end(), ClientSocketDisconnectionTest ), client_socket_list.end() ) ;


 
Merci.

n°610141
Taz
bisounours-codeur
Posté le 13-01-2004 à 09:29:26  profilanswer
 

masi c'est quoi ce bordel ?
 

Code :
  1. #include <iostream>
  2. #include <list>
  3. #include <algorithm>
  4. #include <iterator>
  5. #include <functional>
  6. int main()
  7. {
  8.   int data[13];
  9.   std::list<int> l(data, data + sizeof data / sizeof data[0]);
  10.   std::copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, ", " ));
  11.   std::cout << '\n';
  12.   l.remove_if(std::bind2nd(std::modulus<int>(), 2));
  13.   std::copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, ", " ));
  14.   std::cout << '\n';
  15.   l.remove_if(std::bind2nd(std::less<int>(),  0));
  16.   std::copy(l.begin(), l.end(), std::ostream_iterator<int>(std::cout, ", " ));
  17.   std::cout << '\n';
  18. }


 
après tu regarde si tu veux utilsez des fonctions membres liées (pas static), faut qu'elle soit const, ou mieux, qu'elles aient operator() const
 
après
 
l.remove_if(objet)
 
ou en compliqué
 
l.remove_if(boost::bind1st(boost::mem_fun_ref(&Greeter::hello), g))
 
 

Code :
  1. #include <boost/functional.hpp>
  2. #include <iostream>
  3. #include <algorithm>
  4. #include <string>
  5. struct Greeter
  6. {
  7.   Greeter(const std::string &n)
  8.     : name(n)
  9.   {}
  10.   void hello(const std::string &s) const
  11.   {
  12.     std::cout << this->name << " dit bonjour à " << s << '\n';
  13.   }
  14.   const std::string name;
  15. };
  16. int main()
  17. {
  18.  
  19.   const std::string tab[] = {"Porcinet", "Bouriquet", "Tigrou"};
  20.   Greeter g("Taz" );
  21.   std::for_each(tab, tab + sizeof tab / sizeof *tab, boost::bind1st(boost::mem_fun_ref(&Greeter::hello), g));
  22. }


 
mais comme tu vois faut passer par boost pour pallier a une inconsistence de STL dans sa version actuelle

n°610173
Kristoph
Posté le 13-01-2004 à 10:11:24  profilanswer
 

Attention à ne pas confondre la fonction membre list::remove avec l'algorithme remove.
 
Le premier retire effectivement les elements de la liste ce que ne fait pas l'algorithme remove. Si ton conteneur est une list, il est très très fortement conseiller de passer par list::remove. Dans tous les autres cas il faut faire le v.erase(remove ... indiqué

n°610952
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 19:58:52  profilanswer
 

C'est bete mais remove ne s'utilise pas aussi facilement que erase consécutivement à l'appel de remove_if.
 
Je vais devoir m'interesser à for_each de plus pres, ca a l'air pratique :-)
 
 
 

n°610971
Taz
bisounours-codeur
Posté le 13-01-2004 à 20:13:23  profilanswer
 

euh tu fout quoi là sans déconner ? on te file la solution et tu perds ton temps avec du bordel qui fait pas bien le boulot

n°610981
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 20:20:36  profilanswer
 

On se calme :) Il me faut un peu de temps pour assimiler vos conseils.
 
Merci,
   Xter.

n°611005
Taz
bisounours-codeur
Posté le 13-01-2004 à 20:33:57  profilanswer
 

bah non, tu t'égares. je te guide, exemple à l'appui et toi tu par dans une autre direction, mauvaise et lourde

n°611189
xterminhat​e
Si vis pacem, para bellum.
Posté le 13-01-2004 à 23:33:34  profilanswer
 

Pourquoi as tu besoin d'exploiter boost::, ces fonctions ne sont elle pas déjà définis dans STL ?

n°611194
blackgodde​ss
vive le troll !
Posté le 13-01-2004 à 23:40:12  profilanswer
 

il me semble que le bind de la STL a un problème


---------------
-( BlackGoddess )-
n°611225
Taz
bisounours-codeur
Posté le 14-01-2004 à 00:14:02  profilanswer
 

BlackGoddess a écrit :

il me semble que le bind de la STL a un problème

il est correct, mais la fonction n'est pas surchargé pour tous les cas de constness, etc, boost comble le fossé. boost est parfois plus standard que STL et sera en partie phagocytée

n°611376
blackgodde​ss
vive le troll !
Posté le 14-01-2004 à 09:26:39  profilanswer
 

Taz a écrit :

boost est parfois plus standard que STL et sera en partie phagocytée


 
j'ai deja lu ca :p


---------------
-( BlackGoddess )-
n°611798
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-01-2004 à 17:47:11  profilanswer
 

Tout arrive! J'ai enfin compris et fait trouner une fonction objet avec un for_each. Apres ca, je vais peut etre enfin arrivé à comprendre le std::list.remove_if() :)
 
Merci,
   Xter.

n°611979
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-01-2004 à 21:59:17  profilanswer
 

Bon j'en suis là...
 
list.remove_if(p) : Removes all elements *i such that p(*i) is true
 
Je déclare un objet 'f' avec une fonction membre de telle sorte que f(*i) retourne un bool.
 
J'écrit :  

Code :
  1. list.remove_if(f);


 
Evidemment, cela ne passe pas. Un ptit indice pour m'aider dans la dernière ligne droite ? ;)

n°611982
Kristoph
Posté le 14-01-2004 à 22:00:45  profilanswer
 

f ne doit pas être une fonction membre. Sinon, pourquoi lui passer l'element à tester en paramètre.


Message édité par Kristoph le 14-01-2004 à 22:00:55
n°611984
Taz
bisounours-codeur
Posté le 14-01-2004 à 22:01:42  profilanswer
 

Kristoph a écrit :

f ne doit pas être une fonction membre. Sinon, pourquoi lui passer l'element à tester en paramètre.

f peut être n'importe quoi tant que l'appelle va
 
du code bordel. toute une page, on en est revenu au point de départ

n°611988
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-01-2004 à 22:04:51  profilanswer
 

Code :
  1. // Function Object
  2. template <class x_ClientSocket>
  3. class fTestClientSocketClosed: public std::unary_function< x_ClientSocket, bool >
  4. {
  5. public:
  6.  fTestClientSocketClosed() { }
  7.  bool operator()( const x_ClientSocket & cs ) const { return cs.bClosed; }
  8. };


 
puis
 

Code :
  1. fTestClientSocketClosed <x_ClientSocket> ftcsc ;
  2. client_socket_list.remove_if(ftcsc);


n°611991
Taz
bisounours-codeur
Posté le 14-01-2004 à 22:16:40  profilanswer
 

tu le fais expres avec tes noms de paramètres templates ou quoi ?
 

Code :
  1. #include <list>
  2. struct Foo
  3. {
  4.   bool operator()(int i) const
  5.   {
  6.     return i;
  7.   }
  8. };
  9. int main()
  10. {
  11.   std::list<int> l;
  12.   Foo f;
  13.   l.remove_if(f);
  14. }

n°611995
xterminhat​e
Si vis pacem, para bellum.
Posté le 14-01-2004 à 22:23:50  profilanswer
 

Bon on doit pas avoir le meme compiloe, car on a ecrit la même chose et chez moi rien ne passe.
 
Visual Touch....

mood
Publicité
Posté le   profilanswer
 

 Page :   1  2
Page Précédente

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C++

  [C++/STL] Retrait d'un élément dans une list

 

Sujets relatifs
[C++] liste chainée de struct avec la STL[HTML]mettre un élément tout en haut a gauche
STL : Multimap[C++] STL et complexité
STL - Multimap[VB6] Tableaux dynamiques, effacer un element.
Choisir élément aléatoire?[c] afficher un élément d'une structure complexe de type hostent
Detruire un element d'un InnerHtmlVba Excel et élément de menu personnalisé
Plus de sujets relatifs à : [C++/STL] Retrait d'un élément dans une list


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR