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

 C++ Discussion :

Définir un extrait de vecteur avec des itérateurs.


Sujet :

C++

  1. #1
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut Définir un extrait de vecteur avec des itérateurs.
    Bonjour.

    Je souhaiterais avoir un précision sur l'utilisation des itérateurs.

    Je code des fonctions qui traitent des données (des points x, y, z) contenues dans un std::vector. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void foo(const std::vector<point>& begin, const std::vector<point>& end)
    {
       ...
    }
    Puis j'ai une procédure qui appelle ces fonctions :
    - tant qu'on n'est pas interrompu
    - acquisition des points
    - insertion des points dans le vecteur (push_back)
    - appel de la fonction de traitement sur les derniers points insérés
    - fin du tant que et rebouclage

    Je me suis demandé si je pouvais utiliser l'itérateur .end() obtenu avant les push_back en tant qu'itérateur begin et l'itérateur .end() obtenu après les push_back en tant qu'itérateur end pour appeler ma fonction de traitement.

    J'ai donc réalisé ce petit bout de test qui semble fonctionner.
    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
    #include <cassert>
    #include <iostream>
    #include <vector>
     
    int main(int argc, char **argv)
    {
      std::vector<int> foo;
     
      foo.push_back(1);
      foo.push_back(2);
      foo.push_back(3);
     
      std::vector<int>::iterator i1 = foo.end();
     
      foo.push_back(4);
     
      std::vector<int>::iterator i2 = foo.end() - 1;
      std::vector<int>::iterator i3 = foo.end();
     
      assert(i1 == i2);
      assert((i1 + 1) == i3);
     
      std::cout << *i1 << std::endl;
     
      return 0;
    }
    Ma question est : est-ce l'implémentation qui fait que ça marche, ou est-ce un comportement décrit dans le standard ?

    Je trouve en particulier douteux qu'un itérateur qu'on a obtenu avec end() à un moment ne soit pas le même après insertion de nouveaux éléments...

    Merci pour votre aide.

  2. #2
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    L'itérateur d'un vecteur est un random_access_iterator, qui est un bidirectional_iterator, sur lequel tu peux donc faire du +, du -, etc. v.end() renvoie nécessairement un itérateur valide (mais qui ne peut pas être déréférencé) pointant après le dernier élément. effectuer l'opération {x = v.end(); --x; } permet donc de revenir sur le dernier élément.

    Ce comportement est standard ET nécessaire, sans quoi v.insert(v.end(),...) ne pourrait pas fonctionner.

    Donc tu peux y aller franco

    PAR CONTRE : push_back() invalide les itérateurs. Du coup, un itérateur acquis avant l'exécution de cette fonction n'est plus valide (dans la pratique, il le sera tant que le vecteur ne change pas de capacity(), mais étant donné que tu a peu de contrôle sur le moment ou capacity() change, tu peux considérer que dès l'appel à push_back(), tout tes itérateurs acquis avant sont morts).

    Je trouve en particulier douteux qu'un itérateur qu'on a obtenu avec end() à un moment ne soit pas le même après insertion de nouveaux éléments...
    Sauf que le vecteur est redimensionné automatiquement, et pour cela (puisqu'il a besoin d'une zone mémoire contigüe) il doit ré-allouer une zone mémoire de la bonne taille et détruire l'ancienne. L'itérateur acquis avant cette opération va donc pointer sur une zone mémoire qui n'est plus valide.

    Ce que tu peux faire, c'est garder la taille du vecteur avant insertion de nouveaux éléments ; ensuite, il te suffira de retrouver l'itérateur du dernier élément avant ajout en faisait (v.begin() + taille).
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  3. #3
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Bonjour.

    Merci pour cette réponse qui lève tous mes doutes.

    Je vais donc suivre vos recommandations.

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 36
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    PAR CONTRE : push_back() invalide les itérateurs.
    Ce n'est pas vrai pour tous les conteneurs, par exemple les list.

  5. #5
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    Citation Envoyé par titibete Voir le message
    Ce n'est pas vrai pour tous les conteneurs, par exemple les list.
    Non, mais il utilises un vecteur.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 36
    Points : 33
    Points
    33
    Par défaut
    Citation Envoyé par Emmanuel Deloget Voir le message
    Non, mais il utilises un vecteur.
    Il semblerait que je me soit un peu précipité pour répondre...

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 16/07/2013, 15h26
  2. Gestion de vecteurs avec des scalaires
    Par Xen956 dans le forum Simulink
    Réponses: 4
    Dernier message: 09/07/2012, 09h14
  3. Problèmes syntaxiques avec des itérateurs
    Par Nihi777 dans le forum SL & STL
    Réponses: 4
    Dernier message: 17/05/2011, 20h13
  4. Réponses: 2
    Dernier message: 06/04/2007, 11h30
  5. cpu trop élevé avec des doubles vecteurs
    Par kuzloka dans le forum C++
    Réponses: 8
    Dernier message: 26/12/2005, 19h29

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