std::vector : Passer de l’itérateur à l’indice et vice-versa

Le container std::vector a ceci de particulier que tous ses éléments sont placés dans des zones mémoires contigües. C’est donc le container à privilégier dès lors qu’on a besoin de parcourir un ensemble d’éléments rapidement. Un effet pervers de cette rapidité et que la suppression ou l’ajout d’un élément oblige parfois à réallouer tout le vector ( il faut en effet disposer d’une quantité de mémoire suffisante et contigüe ).Il existe divers moyens pour contrecarrer ces effets ( cf ici : à savoir utiliser la fonction membre .reserve() et l’utilisation d’un double buffer ).

Après cette brève introduction, venons en au sujet,on suppose l’existence de std::vector<int> v :

  • Passer de l’indice à l’itérateur : On veut avoir un itérateur sur le 4ième élément de notre vector.Il suffit de faire: std::vector<int>::iterator = v.begin() + 4; On peut également utiliser std::advance comme décrit sur ce site de référence .
  • Plus rare maintenant, le passage d’un itérateur à l’indice. Il faut utiliser la fonction std::distance . Il existe 2 prototypes de cette fonction mais seule la plus récente est à utiliser ( la première étant dépréciée car buggée etc… ).Je donne la fonction que j’utilise telle qu’elle :
    void CRunner::Kill(IBullet* bullet){
    std::vector&lt;
    IBullet*&gt;::iterator it = std::find(mBullets.begin(),mBullets.end(),bullet);
    
    std::vector&lt;int&gt;::difference_type id = std::distance(mBullets.begin(),it);
    mFreeBullets[mStoreIndex].push_back(id);
    }
    

J’espère que cela vous aura aidé.

Nb: Différence intéressante, l’utilisation d’at() est équivalente à celle de l’opérateur [] à ceci près qu’elle lève une exception si jamais on se place hors du tableau. Par exemple: 

v.push_back(3);// on insere l'element '3' qui a pour indice 0
v[1];// provoque une segmentation fault bof bof pour l'image donnée à l'utilisateur
v.at(1); // lancera une exception qu'on peut attraper et l'utilisateur sait au moins qu'on a pensé à prendre en compte cette erreur

Nb2: Voir la FAQ C++ de developpez.com pour savoir comment choisir le container approprié.

3 Responses to “std::vector : Passer de l’itérateur à l’indice et vice-versa”


  • Je cite: « En effet la tête de disque dur n’a pas à faire des allers et retours mais juste à avancer du même écart à chaque fois. ».
    Heureusement qu’un tableau de type std:vector créé dynamiquement n’est pas stocké sur le disque dur… Le raisonnement est cependant vrai mais les explications sont bien plus complexes (incrément du pointeur de zone mémoire pointé vs ajout d’un chiffre au pointeur déclaré si je ne me trompe… ?) …

    A l’avenir merci de faire attention à ce que vous écrivez…

  • Bien évidemment que ca n’a rien à voir avec les accès disque dur ( je ne m’explique pas cette erreur :s ) 10^5 fois plus lents que la ram. Pour l’explication exacte, je ne saurai expliquer avec certitude donc je m’abstiendrai ( je l’avais lu dans un sujet qu’il faudrait que je retrouve, de toute manière je me renseigne et je mets à jour l’article ).

    J’ai lu ceci sur ton CV:
    « Projet personnel : Génération aléatoire de terrain.
    Optimisation, implémentation de l’algorithme RMDA de génération pseudo aléatoire de terrain (C++, OpenGL sous Linux). »
    Je serai très intéressé si tu pouvais partager ce code ( ca fait partie de ma roadmap et si je peux éviter de le coder :p ).

    Btw cette année SudriaBotik avait un robot vraiment très esthétique. J’étais parmi vos plus grands fans ( d’autant plus que votre équipe avait les plus jolies filles de la coupe ^^ ) et cela me désolait de voir le manque de fiabilité du robot sur les tables d’entraînement. Il vous a manqué pas grand chose.

  • Salut,

    En effet cette année là nous avons eu des problèmes de fiabilité…

    J’ai redéveloppé l’algorithme de génération aléatoire de terrain. Tu peux trouver les sources sur mon site web (projet eclipse)

    N’hésite pas a me contacter par mail si tu as des questions et/ou si tu souhaites apporter des évolution (je pourrais mettre un svn en place au besoin).

    Cordialement,

    Olivier cherrier

Laisser un commentaire