I want to use a circular list.
Short of implementing my own (like this person did) what are my options?
Specifically what I want to do is iterate over a list of objects. When my iterator reaches the end of the list, it should automatically return to the beginning. (Yes, I realize this could be dangerous.)
See Vladimir's definition of a circular_iterator
: "A circular_iterator will never be equal with CircularList::end(), thus you can always dereference this iterator."
There's no standard circular list.
However, there is a circular buffer in Boost, which might be helpful.
If you don't need anything fancy, you might consider just using a vector
and accessing the elements with an index. You can just mod
your index with the size of the vector to achieve much the same thing as a circular list.
If you want something looking like an iterator you can roll your own, looking something like
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;}}
};
(Other iterator operations left as exercise to reader).
list<int>::iterator circularNext(list<int> &l, list<int>::iterator &it)
{
return std::next(it) == l.end() ? l.begin() : std::next(it);
}
In addition to @captain-segfault and @mahmoud-khaled's iterator-focused answers, you can also use std::list
as a circular list by altering what you do to retrieve elements from it. Use splice to move one end of the list to the other end as you process it.
template <typename T>
T & circularFront(std::list<T> & l)
{
l.splice(l.end(), l, l.begin());
return l.back();
}
template <typename T>
T & circularBack(std::list<T> & l)
{
l.splice(l.begin(), l, l.rbegin());
return l.front();
}
来源:https://stackoverflow.com/questions/947489/does-a-standard-implementation-of-a-circular-list-exist-for-c