将std :: list扩展为cylic列表

Man*_*d3r 1 c++ iterator list

我想基于std :: list实现循环列表.我希望从列表的优点中获益,但添加一个特定的功能:它的迭代器运算符++和 - 应跳过边缘并且操作(插入/擦除)不得使现有的迭代器无效.我处理模板的技巧很弱,理解std容器对我来说是不可能的行为.因此我需要你的帮助.到现在为止我还没那么远:D.对不起,即使是很多帖子都没有帮助我.

编辑:经过大量的工作,一个steeeep学习曲线,从std :: list :: iterator继承的失败方法,一个短暂的抑郁和一个缓慢的回归你的方法(是的,你们都是对的)我终于做好了.受到你所有观点的启发,我现在可以发布我上次做的...大约12个小时:D基本上你的建议,但是有很好的小操作员.

#pragma once
#include <list>
using std::list;

template<class T>
class cyclic_iterator;


template<class T>
class cyclicList : public list<T>
{
public:
  typedef cyclic_iterator<T> cyclic_iterator;

  cyclic_iterator cycbegin()
  {// not the purpose, but needed for instanziation
    return cyclic_iterator( *this, this->begin());
  }

  cyclic_iterator cycend()
  {// not the purpose, but needed for instanziation
    return cyclic_iterator( *this, this->end());
  }
};




template<class T>
class cyclic_iterator
{
  public:
  // To hop over edges need to know the container
  cyclic_iterator(){}
  cyclic_iterator(typename list<T>::iterator i)
    : mIter(i){}
  cyclic_iterator(list<T> &c)
    : mContainer(&c){}
  cyclic_iterator(list<T> &c, typename list<T>::iterator i)
    : mContainer(&c), mIter(i){}

  cyclic_iterator<T>& operator=(typename list<T>::iterator i)
  {// assign an interator
    mIter = i;
    return *this;
  }

  cyclic_iterator<T>& operator=(list<T> &c)
  {// assign a container
    mContainer = &c;
    return *this;
  } 

  bool operator==(const cyclic_iterator<T>& rVal) const
  {// check for equality
    return (this->mIter == rVal.mIter && this->mContainer == rVal.mContainer) ? true : false;
  } 

  bool operator!=(const cyclic_iterator<T>& rVal) const
  {//  check for inequality
    return !(this->operator==(rVal));
  } 

  cyclic_iterator<T>& operator++()
  {// preincrement
    ++mIter;
    if (mIter == mContainer->end())
      { mIter = mContainer->begin(); }
    return *this;
  }

  cyclic_iterator<T> operator++(int)
  { // postincrement
    cyclic_iterator<T> tmp = *this;
    ++*this;
    return tmp;
  }

  cyclic_iterator<T>& operator--()
  {// predecrement
    if (mIter == mContainer->begin())
      mIter = --mContainer->end();
    else --mIter;
    return *this;
  }

  cyclic_iterator<T> operator--(int)
  {// postdecrement
    cyclic_iterator<T> tmp = *this;
    --*this;
    return tmp;
  }

  cyclic_iterator<T>& operator+=(int j)
  {// hop j nodes forward
    for (int i = 0; i < j; ++i)
      ++(*this);
    return *this;
  }

  cyclic_iterator<T>& operator-=(int j)
  {// hop j nodes backwards
    for (int i = 0; i < j; ++i)
      --(*this);
    return *this;
  }

  T& operator*()
  {
    return *mIter;
  }

  typename list<T>::iterator & getStdIterator()
  {
    return mIter;
  }

private:  
  list<T>*          mContainer;
  typename list<T>::iterator mIter;

};
Run Code Online (Sandbox Code Playgroud)

Ker*_* SB 5

你能不能只做一个不同的迭代器类型?

#include <iterator>
#include <list>

template <typename T, typename Alloc>
struct cyclic_iterator
: std::iterator<typename std::list<T, Alloc>::iterator::iterator_category, T>
{
    typedef std::list<T, Alloc> list_type;

    cyclic_iterator & operator++()
    {
        ++iter;
        if (iter == container.end()) { iter = container.begin(); }
        return *this;
    }

    T & operator*() { return *iter; }

    cyclic_iterator(typename list_type::iterator it, list_type & l)
    : iter(it)
    , container(l)
    {
        if (it == container.end()) { it = container.begin(); }
    }

    // everything else

private:
    typename list_type::iterator iter;
    list_type & container;
};
Run Code Online (Sandbox Code Playgroud)

有了帮手:

template <typename List>
cyclic_iterator<typename List::value_type, typename List::allocator_type>
make_cyclic_iterator(typename List::iterator it, List & l)
{
    return cyclic_iterator<typename List::value_type, typename List::allocator_type>(it, l);
}
Run Code Online (Sandbox Code Playgroud)

用法:

// goes round and round forever

for (auto ci = make_cyclic_iterator(mylist.begin(), mylist); ; ++ci)
{
    std::cout << *ci << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

(通过一些修改,可以使这个代码适用于任何暴露begin/ end迭代器的容器.)