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

SL & STL C++ Discussion :

find sur le vector


Sujet :

SL & STL C++

  1. #1
    Membre éprouvé Avatar de LeXo
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 147
    Par défaut find sur le vector
    Bonjour

    voila j'ai un soucis sur le find
    si je fais


    j'ai une méthode de classe

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void deleteClient(Client p){
     
    it=find(it,vClient.begin(),vClient.end(),p);
    vClient.erase(it);
    }
    mais quand je compile il met fais plein d'erreur

    alors la question que je me posais ??

    est ce que le find ne prend que des type primitifs ?

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    tu as un iterateur de trop dans ton find.

    ton code devrait ressembler à :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    TonVector::iterator ite = find( vClient.begin(), vClient.end(), p );
    Et pour que ça marche, il faut que tu definisses un operator==( const Client&, const Client &).

  3. #3
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    nikko34 a parfaitement raison. Je rajouterais juste 2 petites remarques en passant:
    1. pour ce ce code fonctionne, il faut que ta classe client possède un opérateur == (ou que ce soit un POD) <edit>grilled</edit>
    2. je te conseilles de vérifier que ton find ait bien trouvé l'objet recherché avant d'utiliser l'iterateur ( dans l'exemple de nikko34, ça donnerais: if (ite!=vClient.end()) )

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par r0d Voir le message
    2. je te conseilles de vérifier que ton find ait bien trouvé l'objet recherché avant d'utiliser l'iterateur ( dans l'exemple de nikko34, ça donnerais: if (ite!=vClient.end()) )
    oui sinon ton erase il va supprimer le dernier élément, ou en tout cas faire n'importe quoi si le find n'a pas trouvé le bon.

  5. #5
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    oui sinon ton erase il va supprimer le dernier élément, ou en tout cas faire n'importe quoi si le find n'a pas trouvé le bon.
    Non, ça ne supprimera pas le dernier élément, ni faire n'importe quoi, ça va crasher tout simplement ( déréférencement de vClient.end() => crash )

  6. #6
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Salut,

    Sinon si le but est de retirer du vecteur les éléments égaux à p tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vClient.erase( std::remove( vClient.begin(), vClient.end(), p ), vClient.end() );
    MAT.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par r0d Voir le message
    Non, ça ne supprimera pas le dernier élément, ni faire n'importe quoi, ça va crasher tout simplement ( déréférencement de vClient.end() => crash )
    dans le petit test que j'ai fait il n'a pas crashé, il a juste effacé le dernier. Comme si j'avais fait v.erase( v.end() - 1 ); Sauf que là c'est a.erase( v.end() ); ( qui ne crashe pas... forcément ).

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    Salut,

    Sinon si le but est de retirer du vecteur les éléments égaux à p tu peux aussi faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    vClient.erase( std::remove( vClient.begin(), vClient.end(), p ), vClient.end() );
    MAT.
    ouaip, en plus si "p" ne correspond à aucun élement du tableau, il ne fait rien.

  9. #9
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    dans le petit test que j'ai fait il n'a pas crashé, il a juste effacé le dernier. Comme si j'avais fait v.erase( v.end() - 1 ); Sauf que là c'est a.erase( v.end() ); ( qui ne crashe pas... forcément ).
    C'est parce que le résultat est un comportement indéterminé qui recouvre aussi bien avoir l'air de faire ce qu'on veut que ça fasse que faire n'importe quoi, faire un truc spécifique irrationnel, ne rien faire, planter, etc...

    MAT.

  10. #10
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par Mat007 Voir le message
    C'est parce que le résultat est un comportement indéterminé qui recouvre aussi bien avoir l'air de faire ce qu'on veut que ça fasse que faire n'importe quoi, faire un truc spécifique irrationnel, ne rien faire, planter, etc...
    MAT.
    c'est ce que je voulais dire par "faire n'importe quoi"

  11. #11
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Intéressant. J'avais cru lire dans le standard que l'itérateur end() d'un conteneur ne devait pas être déréférençable. Mais en effet, j'ai parcouru les documents que j'ai à ma disposition et je n'ai rien retrouvé de tel, c'est bien un comportement indéterminé. Méa culpa

    @nikko34 (par curiosité) : quelle implémentation de la STL (compilo/ide) as-tu utilisé pour ton test?

  12. #12
    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 : 50
    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
    Par défaut
    Citation Envoyé par Le standard, 24.1.5
    Values of an iterator i for which the expression *i is defined are called dereferenceable. The library never assumes that pasttheend values are dereferenceable.
    Donc déréférencer end() n'est pas défini.
    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.

  13. #13
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    Citation Envoyé par r0d Voir le message
    Intéressant. J'avais cru lire dans le standard que l'itérateur end() d'un conteneur ne devait pas être déréférençable. Mais en effet, j'ai parcouru les documents que j'ai à ma disposition et je n'ai rien retrouvé de tel, c'est bien un comportement indéterminé. Méa culpa

    @nikko34 (par curiosité) : quelle implémentation de la STL (compilo/ide) as-tu utilisé pour ton test?
    avec GCC 4.1.0

  14. #14
    Membre éprouvé Avatar de LeXo
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 147
    Par défaut
    désolé pour la faute de l'iterator en plus
    j'ai pas été capable de copier le code


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void deleteClient(Client p){
     
    it=find(vClient.begin(),vClient.end(),p);
    vClient.erase(it);
    }
    j'ai essayé
    en utilisant remove mais il me fait la même error
    Client*, _Container = std::vector<Client, std::allocator<Client> >]() == __val'
    /root/arm/usr/bin-ccache/../lib/gcc/arm-linux-uclibc/4.2.1/../../../../arm-linux-uclibc/include/c++/4.2.1/bits/stl_algo.h:216: error: no match for 'operator==' in '__first. __gnu_cxx::__normal_iterator<_Iterator, _Container>::operator* [with _Iterator = Client*, _Container = std::vector<Client, std::allocator<Client> >]() == __val'
    je n'arrive pas a interpréter cette erreur
    pbm de librairie SL ? j'ai include <vector>
    alors pbm de container ?

    d'avance merci

  15. #15
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 290
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nikko34 Voir le message
    Et pour que ça marche, il faut que tu definisses un operator==( const Client&, const Client &).
    Citation Envoyé par r0d Voir le message
    1. pour ce ce code fonctionne, il faut que ta classe client possède un opérateur == (ou que ce soit un POD)

  16. #16
    Membre éprouvé Avatar de LeXo
    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    1 147
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Janvier 2004
    Messages : 1 147
    Par défaut
    au risque de paraitre beta, il me semble que j'ai compris

    on surchage, l'operateur d'egalite pour comparer 2 clients
    j'ai ajouter

    dans ma classe Client

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    bool operator==(const Client& c1, const Client& c2){
    	return c1.getSock()==c2.getSock();
    }
    mais
    must take exactly one argument

  17. #17
    Membre Expert

    Profil pro
    Inscrit en
    Juin 2006
    Messages
    1 294
    Détails du profil
    Informations personnelles :
    Localisation : Royaume-Uni

    Informations forums :
    Inscription : Juin 2006
    Messages : 1 294
    Par défaut
    Un opérateur de comparaison membre a cette forme-là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Client
    {
    ...
    public:
        bool operator==(const Client& rhs) const {
    	return getSock()==rhs.getSock();
        }
    ...
    };
    Sinon pour une fonction libre (donc en dehors de la déclaration de la classe) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    inline bool operator==(const Client& c1, const Client& c2){
        return c1.getSock()==c2.getSock();
    }
    (ou pas inline si tu mets juste la déclaration et ajoutes la définition dans un .cpp)

    MAT.

  18. #18
    Membre émérite
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Par défaut
    il est conseillé de faire operator==() non membre ( hors classe ) pour être sûr qu'il n'y ait pas de différence de traitement entre les deux opérandes.

    Tu peux en faire une "friend" de ta classe si tu as besoin d'accéder à des données protected/private.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    class TaClasse
    {
        friend bool operator==( const TaClasse & c1, const TaClasse & c2 );
    };
     
    inline bool operator==( const TaClasse & c1, const TaClasse & c2 )
    {}

Discussions similaires

  1. find sur un vector qui contient une structure
    Par kunda dans le forum SL & STL
    Réponses: 14
    Dernier message: 28/04/2009, 21h35
  2. Réponses: 7
    Dernier message: 18/04/2006, 17h44
  3. Réponses: 15
    Dernier message: 20/09/2005, 09h54
  4. std::sort() sur std::vector()
    Par tut dans le forum SL & STL
    Réponses: 20
    Dernier message: 05/01/2005, 19h15
  5. [debutant STL] question sur les vectors
    Par killerjeff dans le forum SL & STL
    Réponses: 13
    Dernier message: 19/08/2004, 17h32

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