Infinite loop printing a list
<p>I have a class List:</p>

<pre><code>#ifndef UTIL_H
#define UTIL_H

#include &lt;iostream&gt;
#include &lt;exception&gt;

namespace Util
{

class IndexOutOfBounds : public std::exception
{
    virtual const char* what()
    {
        return "Index out of bounds";
    }
};

template&lt;class T&gt;
class Iterator;

template &lt;class T&gt;
class ListNode
{

    template&lt;class R&gt;
    friend class Iterator;
    template&lt;class R&gt;
    friend class List;

    public:

    ListNode()
    {
        init();
    }
    ListNode(T info)
    {
        init();
        this-&gt;info=info;
    }
    static void link(ListNode&lt;T&gt; first, ListNode&lt;T&gt; second)
    {
        first.next=&amp;second;
        second.prev=&amp;first;
    }
    template&lt;class R&gt;
    friend std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out, const ListNode&lt;R&gt;&amp; node);
    template&lt;class R&gt;
    friend std::istream&amp; operator&gt;&gt; (std::istream&amp; in, const ListNode&lt;R&gt;&amp; node);

    private:

    T info;
    ListNode&lt;T&gt;* next;
    ListNode&lt;T&gt;* prev;
    void init()
    {
        next=prev=this;
    }
};

template&lt;class T&gt;
std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out , const ListNode&lt;T&gt;&amp; node)
{
    out &lt;&lt; node.info;
    return out;
}

template&lt;class T&gt;
std::istream&amp; operator&gt;&gt; (std::istream&amp; in , const ListNode&lt;T&gt;&amp; node)
{
    in &gt;&gt; node.info;
    return in;
}

template &lt;class T&gt;
class List
{
    friend class ListNode&lt;T&gt;;
    template &lt;class R&gt;
    friend class Iterator;
    private:

    unsigned int length;
    ListNode&lt;T&gt;* node;

    public:

    List()
    {
        node=new ListNode&lt;T&gt;();
        length=0;
    }
    unsigned int size() const
    {
        return length;
    }
    void insert(int i,T info) throw()
    {
        ListNode&lt;T&gt;* ptr=node,*next_ptr;
        try
        {
            if(i&gt;(int)length || i&lt;0)
                throw IndexOutOfBounds();
            for(int j=0;j&lt;i;j++)
                ptr=ptr-&gt;next;
            next_ptr=ptr-&gt;next;
            ptr-&gt;next=new ListNode&lt;T&gt;(info);
            ptr-&gt;next-&gt;prev=ptr;
            ListNode&lt;T&gt;::link(*(ptr-&gt;next),*next_ptr);
            length++;
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    void push_back(T info) throw()
    {
        try
        {
            insert(length,info);
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    void push_front(T info) throw()
    {
        try
        {
            insert(0,info);
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    void remove(int i) throw()
    {
        ListNode&lt;T&gt;* ptr=node,*next_ptr;
        try
        {
            if(i&gt;=length || i&lt;0)
                throw IndexOutOfBounds();
            for(int j=0;j&lt;i;j++)
                ptr=ptr-&gt;next;
            next_ptr=ptr-&gt;next-&gt;next;
            delete ptr-&gt;next;
            ListNode&lt;T&gt;::link(*ptr,*next_ptr);
            length--;
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    void pop_back() throw()
    {
        try
        {
            remove(length-1);
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    void pop_front() throw()
    {
        try
        {
            remove(0);
        }
        catch(IndexOutOfBounds&amp; e)
        {
            throw e;
        }
    }
    Iterator&lt;T&gt; begin() const
    {
        Iterator&lt;T&gt; result;
        result.ptr=node-&gt;next;
        return result;
    }
    Iterator&lt;T&gt; last() const
    {
        Iterator&lt;T&gt; result;
        result.ptr=node-&gt;prev;
        return result;
    }
    Iterator&lt;T&gt; end() const
    {
        Iterator&lt;T&gt; result;
        result.ptr=node;
        return result;
    }
    template &lt;class R&gt;
    friend std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out , const List&lt;R&gt;&amp; l) ;
    template &lt;class R&gt;
    friend std::istream&amp; operator&gt;&gt; (std::istream&amp; in , const List&lt;R&gt;&amp; l);
    typedef Iterator&lt;T&gt; iterator;

};

template&lt;class T&gt;
std::ostream&amp; operator&lt;&lt; (std::ostream&amp; out ,const List&lt;T&gt;&amp; l)
{
    int k=0;
    for(Iterator&lt;T&gt; i=l.begin();i!=l.end();++i)
        out &lt;&lt; *i &lt;&lt; "\t";
    return out;
}

template&lt;class T&gt;
std::istream&amp; operator&gt;&gt; (std::istream&amp; in , const List&lt;T&gt;&amp; l)
{
    for(Iterator&lt;T&gt; i=l.begin();i!=l.end();i++)
        in &gt;&gt; *i;
    return in;
}

template &lt;class T&gt;
class Iterator
{
    friend class List&lt;T&gt;;
    friend class ListNode&lt;T&gt;;
    private:

    ListNode&lt;T&gt;* ptr;

    public:

    Iterator()
    {
        ptr=NULL;
    }
    Iterator(const Iterator&lt;T&gt;&amp; i)
    {
        ptr=i.ptr;
    }
    Iterator&lt;T&gt;&amp; operator= (Iterator&lt;T&gt; i)
    {
        ptr=i.ptr;
        return *this;
    }
    Iterator&lt;T&gt;&amp; operator++ ()
    {
        ptr=ptr-&gt;next;
        return *this;
    }
    Iterator&lt;T&gt; operator++ (int)
    {
        Iterator&lt;T&gt; i=*this;
        ++*this;
        return i;
    }
    Iterator&lt;T&gt;&amp; operator-- ()
    {
        ptr=ptr-&gt;prev;
        return *this;
    }
    Iterator&lt;T&gt; operator-- (int)
    {
        Iterator&lt;T&gt; i=*this;
        --*this;
        return i;
    }
    T&amp; operator* ()
    {
        return ptr-&gt;info;
    }
    template&lt;class R&gt;
    friend bool operator!= (const Iterator&lt;R&gt;&amp; i, const Iterator&lt;R&gt;&amp; j);
    template&lt;class R&gt;
    friend bool operator== (const Iterator&lt;R&gt;&amp; i, const Iterator&lt;R&gt;&amp; j);

};

template &lt;class T&gt;
bool operator!= (const Iterator&lt;T&gt;&amp; i, const Iterator&lt;T&gt;&amp; j)
{
    return i.ptr!=j.ptr;
}

template &lt;class T&gt;
bool operator== (const Iterator&lt;T&gt;&amp; i, const Iterator&lt;T&gt;&amp; j)
{
    return i.ptr==j.ptr;
}

}

#endif
</code></pre>

<p>If in the main I try to print it:</p>

<pre><code>int main(int argc, char** argv)
{
List&lt;int&gt; l;
for(int i=0;i&lt;10;i++)
    l.push_back(i);
std::cout &lt;&lt; l;
return 0;
}
</code></pre>

<p>I get the screen full of numbers flowing, I have to kill the process from terminal.
So it goes into ain infinite loop and I don't understand why.
Maybe the Iterator operator != has some issue, I don't understand.</p>
