Итератор для vector<vector<T> >
От: LightGreen  
Дата: 12.01.14 12:21
Оценка: 1 (1)
Подскажите, люди знающие, как грамотно сделать итератор для vector<vector<T> > так, чтобы внешняя семантика оставалась, как у итератора одного контейнера? Нужно обойти все элементы по одному разу. Типы контейнеров могут быть другими, это не принципиально, например vector<list<T> > или list<list<T> >.
Я пробовал делать по-разному, но всё время возникает одна и та же проблема: непонятно, как сравнивать итераторы в конце — что считать за общий end(). Если внешний it1_ упирается в свой end(), то значение внутреннего it2_ оказывается неопределённым. Поэтому появляются трудности с реализацией функции operator==():
template <class T>
class MyContainer
{
   typedef std::vector<T> Inner;
   typedef std::vector<Inner> Outer;
   Outer contents_;
public:
   class iterator
   {
      friend class MyContainer;
      Outer::iterator it1_;
      Inner::iterator it2_, it2end_;
      bool isEnd_; // <<<<< костыль
      iterator(Outer::iterator it1, bool) : it1_(it1), isEnd(false) {
         it2_ = it1_->begin();
         it2end_ = it1_->end();
      }
      iterator(Outer::iterator it1) : it1_(it1), isEnd(true) {}
   public:
      T& operator*() { return *it2_; }
      iterator& operator++() {
         if(++it2_==it2end_) {
            ++it1_;
            it2_ = it1_->begin();
            it2end_ = it1_->end();
         }
      }
      bool operator==(iterator it) const {
         return it1_==it.it1_ &&
            (isEnd_==it.isEnd_ || it2_==it.it2_);
      }
   };
   
   iterator begin() { return iterator(contents_.begin(), true); }
   iterator end() { return iterator(contents_.end()); }
};


В этом коде используется костыль в виде дополнительной переменной isEnd_, которая устанавливается в true для конца первого контейнера (когда значения it2_ и it2end_ не определены). Это увеличивает размер данных под итератор и количество операций сравнения в шаге цикла for(;it!=itEnd; ). Можно ли данную задачу решить изящнее, без дополнительной переменной и дополнительного сравнения?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.