1

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;
};
6
  • cout is cached, try putting ` << endl` and see if you really dont get there Commented May 11, 2020 at 16:51
  • Please provide a minimal reproducible example. The operator you've implemented is for a Node not an iterator? Commented May 11, 2020 at 16:53
  • it does not work.. Commented May 11, 2020 at 16:56
  • also note, iterator should not be a pointer type unless storage is continuous, like a vector Commented May 11, 2020 at 16:57
  • Can we see the implementation of your begin function? That would be helpful in identifying what's going on. Commented May 11, 2020 at 17:00

2 Answers 2

1

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!

Sign up to request clarification or add additional context in comments.

Comments

0

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;
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.