Reputation: 33
I'm a beginner and now I am trying to implement the class linked list which contains the function begin(). The function return well the first element in the list, but what i am trying to do is to return the iterator on the next position, for instance something like this:
List<int>::iterator iter2 = a.begin() + 2; // or iter2 = iter2 + 1;
cout <<iter2->data;
Where the output is garbage like 21213123..
So here I was thinking I should use an operator overloading+, here is my function:
template<class T>
Node<T>* operator+(const Node<T>& iter, const int& pos)
{
cout << "in"; for testing, but seems that doesnt even entry here
return NULL;
}
So can anyone help me? Thank you very much
P.S: Here is the class Node
template<class T>
class Node {
public:
T data;
Node* next;
Node() :data(0), next(NULL) {}
Node(T val, Node<T>* pointer = NULL) :data(val), next(pointer) {}
};
and list class
template<class T>
class List {
public:
typedef Node<T>* iterator;
typedef const Node<T>* const_iterator;
//constructors
List() { item = NULL; counter = 0; }
explicit List(int val) :counter(1) { item = new Node<T>(val); }
~List() { // to be made
}
//public functions
int size() { return counter; }
iterator begin() {
return item;
}
iterator end()
{
iterator last = item;
while (last->next != NULL)
{
last = last->next;
}
return last;
}
void push_front(const int& val) {
iterator newNode = new Node<T>(val, item);
item = newNode;
counter++;
}
void append(const int& val)
{
iterator newnode = new Node<T>(val);
newnode->next = NULL;
iterator last = item;
if (item == NULL)
{
item = newnode;
return;
}
while (last->next != NULL)
last = last->next;
last->next = newnode;
counter++;
}
int operator[](const int&);
private:
iterator item;
int counter;
};
Upvotes: 1
Views: 239
Reputation: 7644
iterator
for a linked list cannot be a pointer, it needs
to be something like:
struct iterator
{
typedef int difference_type;
typedef T* pointer;
typedef T& reference;
typedef iterator_category std::bidirectional_iterator_tag
iterator();
iterator& operator++();
iterator& operator--();
iterator operator++(int);
iterator operator--(int);
T& operator*();
T* operator->();
bool operator==(iterator rhs) const;
bool operator!=(iterator rhs) const;
private:
iterator(Node*);
Node* node;
};
Upvotes: 0
Reputation: 372714
Let's take a look at your begin
function:
typedef Node<T>* iterator;
iterator begin() {
...
}
This function returns a Node<T>*
, a pointer to a Node<T>
object. As a result, when you write
list.begin() + 2;
C++ interprets this to mean "I've got a pointer, and I've got a number, so I'll step that pointer forward the appropriate number of steps."
You're then asking - well, wait a minute, why isn't this overloaded operator getting called?
template<class T>
Node<T>* operator+(const Node<T>& iter, const int& pos) {
...
}
Take a look at the argument types. This function says "if someone tries adding together an honest-to-goodness Node<T>
object and an int
, here's what I'd like you to do." The problem is that the code
list.begin() + 2
doesn't try adding an honest-to-goodness Node<T>
object and an integer. Instead, it adds a pointer to a Node<T>
object and an integer. And since those types don't match your overloaded operator, it won't even try calling the overloaded operator.
Unfortunately, in C++ you can't overload an operator between two primitive types, so there's no way to write a version of operator+
that takes in a Node<T>*
and an int
, so the fix here isn't as simple as "just make your operator+
function take in a Node<T>*
.
Rather, I'd suggest making your iterator
type an actual class
or struct
rather than a raw pointer. Your iterator will likely work by keeping track of a pointer to some Node<T>
somewhere, but fundamentally the iterator isn't actually just that pointer itself. For example, you might try something like this:
template <class T>
class List {
public:
class iterator {
public:
// some other things, and
iterator operator+ (int step) const;
private:
// some other things, and
Node<T>* current;
};
// some other things, and
iterator begin();
};
Now, you can overload operator+
on the List<T>::iterator
type. That implementation of operator+
can then update the stored Node<T>*
inside the iterator.
Hope this helps!
Upvotes: 1