By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,677 Members | 1,174 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,677 IT Pros & Developers. It's quick & easy.

problem overloading the ++ operator of an iterator

P: 20
Hi,
I have the weirdest problem, and I can not see what is going wrong.
I have made a 2d container class, and am implementing an iterator for that class. However, the ++ operator is behaving very strange. The implementation looks like this (there is a lot of code, but I have only included it all for consistency. The problem is quite small and local):


Expand|Select|Wrap|Line Numbers
  1.  
  2. template<typename T> class Row<T> : public std::vector<T> {};
  3.  
  4. template<typename T> class Grid<T> : public std::vector<Row<T> >
  5. {
  6. public:
  7.  
  8.        class iterator;
  9.  
  10.         iterator
  11.         begin()
  12.         {
  13.             typename std::vector<Row<T> >::iterator it;
  14.             it = this->std::vector<Row<T> >::begin();
  15.             typename Row<T>::iterator ri;
  16.             ri = it->begin();
  17.             iterator ret(it,ri);
  18.             return ret;
  19.         }
  20.  
  21.  
  22.         iterator
  23.         end()
  24.         {
  25.             typename std::vector<Row<T> >::iterator it;
  26.             it = this->std::vector<Row<T> >::end()-1; 
  27.             typename Row<T>::iterator ri;
  28.             ri = it->end();
  29.             iterator ret(it,ri);
  30.             return ret;
  31.         }
  32. };
  33.  
  34. template<typename T>
  35.     class Grid<T>::iterator : public Row<T>::iterator
  36.         {
  37.         private:
  38.             typedef typename std::vector<Row<T> >::iterator row_iterator;
  39.             typedef typename Row<T>::iterator cell_iterator;
  40.  
  41.             row_iterator row_iter;
  42.             cell_iterator cell_iter;
  43.  
  44.         public:
  45.             iterator(){}
  46.             iterator(row_iterator ri, cell_iterator ci) : row_iter(ri), cell_iter(ci) {}
  47.             iterator(const iterator& rhs) : row_iter(rhs.row_iter), cell_iter(rhs.cell_iter) {}
  48.  
  49.             iterator
  50.             operator=(const iterator& rhs)
  51.             {
  52.                 if(this = &rhs) return *this;
  53.  
  54.                 cell_iter = rhs.cell_iter;
  55.                 row_iter = rhs.row_iter;
  56.                 return *this;
  57.             }
  58.  
  59.             T&
  60.             operator*()
  61.             {
  62.                 return *cell_iter;
  63.             }
  64.  
  65.  
  66.             iterator&
  67.             operator++() //prefix   //this is where the problem is!
  68.             {
  69.                 cell_iter++;
  70.                 if (cell_iter == row_iter->end())
  71.                 {
  72.                     std::cout << "end of line" << std::endl;
  73.                     ++row_iter;
  74.                     cell_iter == row_iter->begin();
  75.                 }
  76.                 return *this;
  77.             }
  78.  
  79.  
  80.             bool
  81.             operator==(const iterator& rhs)
  82.             {
  83.                 return (cell_iter == rhs.cell_iter && row_iter == rhs.row_iter);
  84.             }
  85.  
  86.             bool
  87.             operator!=(const iterator& rhs)
  88.             {
  89.                 return (!*this == rhs);
  90.             }
  91.  
  92.  
  93.             void
  94.             test()
  95.             {
  96.                 cell_iter = row_iter->begin();
  97.                 while (cell_iter != row_iter->end()) std::cout << *cell_iter++;
  98.                 ++row_iter;
  99.                 cell_iter = row_iter->begin();
  100.                 std::cout << std::endl;
  101.                 while (cell_iter != row_iter->end()) std::cout << *cell_iter++;
  102.                 std::cout << std::endl << std::endl;
  103.             }
  104.         };
I have added all the code for consistency, but the problem is where I have indicated by my comment.

It should all compile without problems, but has an unwanted behaviour when i test it, e.g.

Expand|Select|Wrap|Line Numbers
  1. #include<iostream>
  2.  
  3. #include "Grid.h"
  4.  
  5. int main()
  6. {
  7.    Grid<int> grid(3,3);
  8.  
  9.     for (int i=0; i != 3; ++i)
  10.     {
  11.         for (int j=0; j!= 3; ++j)
  12.         {
  13.             grid[i][j]=i*3 + j + 1;
  14.         }
  15.     }
  16.  
  17.    std::cout << *(grid.begin()) << std::endl;  
  18.    std::cout << *(--grid.end()) << std::endl; 
  19.  
  20.    Grid<int>::iterator iter3 = grid.begin();  
  21.    iter3.test();                                 // this behaves as expected!
  22.  
  23.    Grid<int>::iterator iter = grid.begin();
  24.  
  25.     for (int i= 0; i!=15; ++i)
  26.     {
  27.         std::cout << *iter << "  ";  // this does not!
  28.         ++iter;
  29.     }
  30. }
when I conduct iter3.test() i get the behaviour i want - it writes
123
456

when i use the ++ operator below, it writes
1 2 3 end of line
## ## ## 4 5 6 end of line
## ## ## 7 8 9 end of line
where ## indicates some undefined number.
I would gladly appreciate any help you could give me, as I have now been looking at this problem for days.
Thanks
Oct 22 '07 #1
Share this Question
Share on Google+
4 Replies


weaknessforcats
Expert Mod 5K+
P: 9,197
I think on line 75 that you need to return cell_iter that you have been incrementing rather than this.
Oct 22 '07 #2

P: 20
I think on line 75 that you need to return cell_iter that you have been incrementing rather than this.
Thanks, but I do not see how that could work?
There is an implicit this->cell_iter++ in line 68. My iterator contains two other iterators:
Expand|Select|Wrap|Line Numbers
  1. Grid<T>::iterator : public Row<T>::iterator
  2. {
  3. typename std::vector<Row<T> >::iterator row_iter;
  4. typename Row<T>::iterator cell_iter;
  5. //...
  6. };
row_iter points at a row in the Grid, and cell_iter moves in that row. My intention with the increment operator is that when cell_iter reaches the end of its row, row_iter should point to the next row, and cell_iter to the first element of that row.
Oct 22 '07 #3

weaknessforcats
Expert Mod 5K+
P: 9,197
Sorry. I was off base on my comment.

However, what about:
++row_iter;
cell_iter == row_iter->begin();
When row_iter == row_iter.end(), cell_iter is set back to row_iter.begin().

Maybe that should be:
Expand|Select|Wrap|Line Numbers
  1. if (++row_iter == row_iter.end()
  2. {
  3.     cell_iter = row_iter.end();
  4. }
  5. else
  6. {
  7.      cell_iter = row_iter.begin();
  8. }
  9. return *this;
  10.  
Oct 22 '07 #4

P: 20
Yes!
Finally it works :) thanks!
Michael
Oct 22 '07 #5

Post your reply

Sign in to post your reply or Sign up for a free account.