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 :

passer un iterator en argument d'une fonction


Sujet :

SL & STL C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut passer un iterator en argument d'une fonction
    Bonjour!

    J'ai une classe du type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    class A{
    vector<list<int> > m_Vect
     
    void fonction(int numelemvector, list<int>::iterator elemliste)
    }
    Le but de cette fonction est de travailler sur une des listes (d'où le numelemvector en paramètre). De plus je voudrais travailler sur la liste à partir d'un certain élément de la liste dont je connais déjà la position, d'où mon idée de passer en argument un list<int>::iterator.

    L'idée du code serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void A::fonction(int, numelemvector, list<int>::iterator elemliste){
    list<int>::iterator lit=elemliste; //car je ne veux pas modifier elemliste, je ne veux que l'information de position qu'il contient
    while(1){
    m_Vect[numelemvector].erase(lit) //par exemple
    lit++;
    //et une condition de sortie de la boucle
    }
    }
    Maintenant, le code où j'appelle "fonction" serait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    A a;
    list<int>::iterator it;
    it=a[i].begin()
    //...
    // après une série d'opérations it renvoit à une position x dans a.m_Vect[i]
    // J'aimerais pouvoir écrire:
    a.fonction(i, it);
    Mes doutes sont les suivants: si l'on crée un iterator (ici it) relativement à une liste bien précise, peut-on le passer en argument d'une fonction? Ici le "this" de fonction correspond bien à la liste avec laquelle it a été défini, mais qu'en est-il si ce n'est pas le cas?

  2. #2
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Bonjour

    Conceptuellement, vector<list<int>> me semble "étrange".

    Votre "elemliste" n'est pas passé en référence dans votre fonction. Elle ne sera donc pas modifié dans le bloc d'appel. Il n'est donc pas nécessaire de créer "lit". Par contre, votre itérateur du bloc principal sera invalidé et ne devra plus être utilisé (il pointe sur un élément supprimé)

    Si vous voulez supprimer tous les éléments à partir de "elemliste", il suffit de mettre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    m_Vect[numelemvector].erase(lit, m_Vect[numelemvector].end());
    Je comprend pas très bien la question "Ici le "this" de fonction correspond bien à la liste avec laquelle it a été défini, mais qu'en est-il si ce n'est pas le cas? ".
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    A a, b;
    list<int>::iterator it = a[i].begin();
    b.fonction(i, it);
    Dans tous les cas, si l'itérateur ne pointe pas vers un élément de la liste, l'appel à erase n'effacera rien.

    Et n'hésitez pas à utiliser des typedef, ca simplifiera la lecture du code.

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    49
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Novembre 2008
    Messages : 49
    Par défaut
    Bonjour,

    merci beaucoup pour la réponse et désolé pour la mienne si tardive!
    J'utilise un vect<list> parce que j'ai plusieurs listes à traiter (plus ou moins des points d'un polygone), et que cela m'a paru la façon la plus simple de les stocker...
    Je comprend pas très bien la question "Ici le "this" de fonction correspond bien à la liste avec laquelle it a été défini, mais qu'en est-il si ce n'est pas le cas? ".
    Finalement, même sans avoir bien compris, l'exemple fourni a répondu à la question.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    A a, b;
    list<int>::iterator it = a[i].begin();
    b.fonction(i, it);
    Dans tous les cas, si l'itérateur ne pointe pas vers un élément de la liste, l'appel à erase n'effacera rien.
    Non seulement cela n'efface rien, mais cela génère une erreur...



    Suite de mes questions en la matière...
    Au début de mon algorithme, je n'ai qu'une seule liste dans mon vect<list>, et au cours de l'exécution, j'en crée de nouvelles et en détruis. Comme je dois passer de l'une à l'autre de ces listes et que je dois retrouver le dernier élément (un des points de la liste donc) que j'ai traité, j'aurais besoin "d'une batterie" d'iterator pointant chacun sur un des points de la liste dans le vecteur... Oui, ça devient compliqué certainement, mais je n'ai pas de meilleure solution pour le moment.
    J'ai essayé donc de créer un vecteur d'itérator de liste, dont chaque élément pointerait sur le point souhaité de chaque liste, mais ça n'a pas vraiment fonctionné:
    En reprenant mon code précédent, cela donnerait quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    A a;
    vect<list<int> >::iterator > vectit;
    vectit[0] = a.m_Vect[0].begin();
    vectit[1] = a.m_Vect[1].begin();
    Mais bon, ça ne fonctionne pas...

  4. #4
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Par défaut
    Quand vous parlez du dernier élément, vous parlez du dernier élément de la list ou le dernier inséré ?
    Dans le premier cas, vous avez la fonction list::back().

    Dans le second cas, pourquoi ne pas passer par une classe qui se chargerait de gérer votre list<int> et conserver un pointeur sur le dernier élément inséré ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    template<class T>
    class List : public std::list<T>
    {
     public:
      typedef std::list<T>::iterator Iterator;
     
      MyIntList() : std::list() {}
     
      insert(Iterator position, const T& x)
      {
       m_last_element = insert(position, x);
      }
     
      Iterator getLastElementInsered() const
      {
       return(m_last_element);
      }
     
     private:
      Iterator m_last_element;
    };
     
    typedef List<int> ListOfInt;
     
    class A
    {
     public:
      vector< ListOfInt > m_Vect;
    };
    Je n'ai pas testé ce code mais l'idée y est : laisser le soins à la classe List de s'occuper des insertions, des suppressions, de recherches, etc.

    PS: 2 métodes : créer une classe héritant de std::list (comme j'ai fait ici) ou une classe contenant un membre std::list.
    Dans le premier cas, les fonctions "standard" de std::list sont disponible (mais ne mettent pas à jour m_last_element, après un erase par exemple). Il est alors de la responsabilité de l'utilisateur de cette classe de savoir quand le pointeur retourné par getLastElementInsered() est invalide.
    Dans le second cas, on ne crée que les fonctions de std::list qui sont réellement utilisées et on peut mettre à jour le pointeur m_last_element (le mettre à m_list.end() par exemple après un erase). Cette méthode est plus sure en général.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Passer variable PHP en argument d'une fonction JS
    Par Vespiras dans le forum Général JavaScript
    Réponses: 16
    Dernier message: 31/01/2013, 09h44
  2. passer un tableau en argument dans une fonction
    Par rogerio dans le forum Débuter
    Réponses: 6
    Dernier message: 30/10/2008, 12h15
  3. Réponses: 9
    Dernier message: 19/10/2006, 10h02
  4. Réponses: 14
    Dernier message: 16/05/2006, 11h26
  5. passer FILE* en argument d une fonction
    Par Monsieur_Manu dans le forum C
    Réponses: 9
    Dernier message: 10/04/2003, 17h56

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