2009-06-03 3 views
20

Je souhaite utiliser une liste circulaire.Existe-t-il une implémentation standard d'une liste circulaire pour C++?

À court d'implémenter le mien (like this person did) quelles sont mes options?

Plus précisément, ce que je veux faire est de parcourir une liste d'objets. Lorsque mon itérateur atteint la fin de la liste, il devrait automatiquement revenir au début. (Oui, je réalise que cela pourrait être dangereux.)

See Vladimir's definition of a circular_iterator: "Un élément circulaire ne sera jamais égal à CircularList :: end(), donc vous pouvez toujours déréférencer cet itérateur."

Répondre

27

Il n'existe pas de liste circulaire standard.

Cependant, il existe un circular buffer dans Boost, ce qui peut être utile.

Si vous n'avez pas besoin de quelque chose de fantaisie, vous pouvez envisager d'utiliser un vector et d'accéder aux éléments avec un index. Vous pouvez juste mod votre index avec la taille du vecteur pour atteindre à peu près la même chose qu'une liste circulaire.

+3

Merci Naaff! Modding l'index avec la taille du vecteur est une solution si simple, je suis gêné je n'y ai pas pensé. – Runcible

+0

Si vous vous assurez que la taille de votre 'vecteur' est une puissance de deux, alors au lieu de l'overhead coûteux de l'opération de module, utilisez l'opérateur bit &' à la place car il ne coûte qu'un cycle. Cela fonctionne comme ceci: '(n mod (2^k)) == (n & (2^k - 1))' p. 'n% 256 == (n & (255))' –

16

Si vous voulez quelque chose qui ressemble à un itérateur vous pouvez rouler votre propre, en regardant quelque chose comme

template <class baseIter> 
class circularIterator { 
    private: 
     baseIter cur; 
     baseIter begin; 
     baseIter end; 
    public: 
     circularIterator(baseIter b, baseIter e, baseIter c=b) 
      :cur(i), begin(b), end(e) {} 
     baseIter & operator ++(void) {++cur; if(cur == end) {cur = begin;}} 
}; 

(Autres opérations iterator gauche comme exercice au lecteur).

Questions connexes