0

I am having issues with my nested iterator class. The end() sentinel is returning 0, and I am very lost! Any help would be appreciated. I want this program to be able to take any type of input, e.g. an int, create the vector, and be able to fill the array until the end() sentinel has been reached, such as typing Q, or any non-integer. I took out a few lines of unnecessary code to shorten it.

template <class T>
class Set
{
    private:
        vector<T> m_element;
        int size;
    public:
        Set() : size(0) {};
        ................
        ................
        ................

        class iterator;
        friend class iterator;
        class iterator
        {
            private:
                int i_index;
                Set& s;
            public:
                iterator(Set& is) :s(is), i_index(0) {}
                iterator(Set& is, bool) : s(is), i_index(s.size) {}
                int operator++()
                {
                    return s.m_element[++i_index];
                }
                (other postfix ++ operator)
                int current() const
                {
                    return s.m_element[i_index];
                }
                ....................
                bool operator!=(const iterator &rv) const
                {
                    return i_index != rv.i_index;
                }
                .............................
                int getI()
                {
                    return i_index;
                }
        };
        iterator begin() { return iterator(*this);}
        iterator end() {return iterator(*this, true);}
};

template <class T>
istream& operator>> (istream &in, Set<T> &element)
{
    T elementin;
    Set<T> is;
    class Set<T>::iterator it = element.begin();
    while(it != element.end())
    {
        in >> elementin;
        element.push(elementin);
    }
    return in;
}

int main()
{
    Set<int> intset;
    Set<int>::iterator it = intset.begin();
    for(int i = 0; i < 5; i++)
    {
        intset.push(i);
        cout << it.getI();
        ++it;
    }

    cout << endl << intset.begin() << intset.end();

    return 0;
}

OUTPUT:
01234
00
jameswoo
  • 386
  • 3
  • 12
  • 2
    Is this some kind of exercise, or could you just use `std::set` or `std::unordered_set` instead? –  Jan 07 '14 at 08:13
  • 1
    The end() indicates 1 past end and not actual end. There have been many discussion on this please go use them for reference http://stackoverflow.com/questions/9963401/why-are-standard-iterator-ranges-begin-end-instead-of-begin-end – Nik Jan 07 '14 at 08:13
  • 1
    @H2CO3 it is an assignment – jameswoo Jan 07 '14 at 08:38

2 Answers2

2

the end iterator points to the "past-the-end" position. You should not try to dereference it.

Moreover, you probably don't want to print intset.begin() (which is the iterator, i.e. pointer) but *(intset.begin()) which is the (pointed-to) element.

Stefano Falasca
  • 8,837
  • 2
  • 18
  • 24
2

1st of all you should provide Short, Self Contained, Correct Example (SSCCE) .

Below program how you could resolve the issue you are facing assuming I have assumed some functions correctly:

#include <iostream>
#include <vector>

using namespace std;


template <class T>
class Set
{
  private:
    vector<T> m_element;
    int size;
  public:
    Set() : size(0) {};
    Set(const Set& rhs)
    {
       m_element = rhs.m_element;
       size = rhs.size;
    }

    void push(T data)
    {

      m_element.push_back(data);
      ++size;
    }

    class iterator;
    friend class iterator;
    class iterator
    {
      private:
        int i_index;
        Set& s;
      public:
        iterator(Set& is) :s(is), i_index(0) {}
        iterator(Set& is, bool) : s(is), i_index(s.size) {}
        iterator(Set& is, bool val,bool last) : s(is), i_index(s.size) {

          cout<<endl<<"size "<<s.size<<endl;
        if(last)
          i_index = s.size -1 ;
        }

        T operator*()
        {
          return s.m_element[i_index];
        }

        int operator++()
        {
          return s.m_element[++i_index];
        }
        int current() const
        {
          return s.m_element[i_index];
        }
        bool operator!=(const iterator &rv) const
        {
          return i_index != rv.i_index;
        }
        int getI()
        {
          return i_index;
        }
    };
    iterator begin() { return iterator(*this);}
//function to check if we have passed last element
        iterator end() {return iterator(*this, true);}
//function to get last element 
        iterator last() {return iterator(*this, true,true);}

};

  template <class T>
istream& operator>> (istream &in, Set<T> &element)
{
  T elementin;
  Set<T> is;
  class Set<T>::iterator it = element.begin();
  while(it != element.end())
  {
    in >> elementin;
    element.push(elementin);
  }
  return in;
}

int main()
{
  Set<int> intset;
  Set<int>::iterator it = intset.begin();
  for(int i = 0; i < 5; i++)
  {
    intset.push(i);
    cout << it.getI();
    ++it;
  }

// cout << endl << intset.begin() << intset.end();
//We use last() to print the last element as end() confirms 
//that we have passed last element and does not point to last element.
  cout << endl << *(intset.begin()) << " " <<*(intset.last())<<endl;

  return 0;
}
Nik
  • 1,294
  • 10
  • 16
  • Thanks so much for your help! It worked after you gave me this code, although I don't understand much what you added to fix it. Could you explain what you added? – jameswoo Jan 07 '14 at 10:15