iterator for a template class containing vector

Hi again,

I'm trying to implement a specialized form of a list, I do not want to inherit from std::vector (I've read that this is not a good idea, though I do not entirely know why yet) so I settled for composition as in the following: (I have already asked a question about this code before, but this one is different)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <vector>
#include <iostream>

#ifndef UTILS_HH
#define UTILS_HH

namespace midurad {
  template<class T>
  class pair {
  private:
    std::vector<T> __pair;
  public:
    pair();
    pair(const T&, const T&);
    pair(const pair<T>&);
    pair<T>& operator=(const pair<T>&);
    bool operator==(const pair<T>&) const;
    const T& operator[](unsigned) const;
    T& operator[](unsigned);
    void swap();
  };

  template<class T>
  pair<T>::pair() {
    __pair = std::vector<T>(2);
  }
  
  template<class T>
  pair<T>::pair(const T& t1, const T& t2) {
    __pair = std::vector<T>(2);
    __pair[0] = t1; __pair[1] = t2;
  }

  template<class T>
  pair<T>::pair(const pair<T>& to_copy) {
    __pair = std::vector<T>(to_copy.__pair);
  }

  template<class T>
  pair<T>& pair<T>::operator=(const pair<T>& to_assign) {
    __pair = to_assign.__pair;
    return *this;
  }

  template<class T>
  const T& pair<T>::operator[](unsigned index) const {
    return __pair[index];
  }

  template<class T>
  T& pair<T>::operator[](unsigned index) {
    return __pair[index];
  }

  template<class T>
  bool pair<T>::operator==(const pair<T>& other) const {
    return (__pair[0] == other[0] && __pair[1] == other[1]) ? true : false;
  }

  template<class T>
  void pair<T>::swap() {
    T second = __pair[1];
    __pair[1] = __pair[0];
    __pair[0] = second;
  }

  template<class T>
  class pair_list {
  private:
    std::vector<pair<T> > __list;
  public:
    pair_list();
    bool contains(const pair<T>&);
    void append(const pair<T>&);
    class iterator;
    friend class iterator;
    class iterator {
    private:
      pair_list<T> __pl;
      bool __end;
      typename std::vector<pair<T> >::iterator __it;
    public:
      iterator(pair_list& pl, bool end) {
	__pl = pl;
	__end = end;
	if(end == true)
	  __it = __pl.__list.end();
	else
	  __it = __pl.__list.begin();
      }
      iterator& operator++() {
	++__it;
	return *this;
      }
      bool operator==(const iterator& other) const {
	return __it == other.__it;
      }
      bool operator!=(const iterator& other) const {
	return __it != other.__it;
      }
      pair<T>& operator*() const {
	return *__it;
      }
    };

    iterator begin() {
      return iterator(*this, false);
    }

    iterator end() {
      return iterator(*this, true);
    } 
  };
  
  template<class T>
  pair_list<T>::pair_list() {
    __list = std::vector<pair<T> >();
  }

  template<class T>
  void pair_list<T>::append(const pair<T>& p) {
    __list.push_back(p);
  }

  template<class T>
  bool pair_list<T>::contains(const pair<T>& p) {
    for(pair_list<T>::iterator it = (*this).begin(); it != (*this).end(); ++it) {
      if(*it == p) return true;
    }
    return false;
  }
}

#endif 


The problem is that when I populate pair_list<int> pl with pairs<int>, and invoke an iterator on it as such:

1
2
3
for(pair_list<int>::iterator it = pl.begin(); it != pl.end(); ++it) {
   // this is infinite loop
}


the loop never exits. I'm pretty sure I correctly defined the operators ==, !=, and prefix ++ for that particular iterator class, but for some reason

 
it != pl.end()


never evaluates to true. Any ideas? As always your help is greatly appreciated. By the way, in my definition of pair_list<T>::contains function, why I don't need to proceed the declaration of the iterator type with typename as I had to in the declaration of the vector iterator in pair_list<T>::iterator? Thanks.
I figured it out. The problem was that when I was creating an instance of an pair_list<int>::iterator I would copy the list that I want to iterate to pair_list<int>::iterator::__pl and invoke the iterator on that. Essentially it boils down to the fact that with this setup calls to begin() and end() would return iterators that were NOT associated with the same list.

Here is the portion of the code that caused problems:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    class iterator {
    private:
      pair_list<T> __pl;
      bool __end;
      typename std::vector<pair<T> >::iterator __it;
    public:
      iterator(pair_list& pl, bool end) {
	__pl = pl;
	__end = end;
	if(end == true)
	  __it = __pl.__list.end();
	else
	  __it = __pl.__list.begin();
      }


and here is what it should be:
1
2
3
4
5
6
7
8
9
10
    class iterator {
    private:
      typename std::vector<pair<T> >::iterator __it;
    public:
      iterator(pair_list& pl, bool end) {
	if(end == true)
	  __it = pl.__list.end();
	else
	  __it = pl.__list.begin();
      }
Topic archived. No new replies allowed.