(How To) Problems with operator<< to output iterators

Hi everyone!

In the last days I made a container class (forward list STL style) and I started to test it.

Everything went fine until I started to test the Iterator part.
When I try to use the output operator, even if it has been overloaded, the compiler gives me this error: undefined reference to `operator<<(std::ostream&, Container<int>::Node const&)'.

Here's the code with the accused parts:


container.h file

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
#include<iostream>
using std::ostream;

template <class T>
class Container {
    friend class Iterator;

private:
    class Node {
        public:
            T info;
            Node*next;
            Node(const T& x, Node*p=nullptr): info(x), next(p) {}
            ~Node() {}
            friend ostream& operator<< (ostream&, const Node&); //overloaded node output operator
    };

    Node*first;

public:
    class Iterator {
        friend class Container<T>;

    private:
        Container::Node*point;

    public:
        bool operator== (Iterator) const;
        bool operator!= (Iterator) const;
        Iterator& operator++ ();
        Iterator operator++ (int);
        Node* operator-> () const;
        Node& operator* () const;
    };

    Container() : first(nullptr) {}
    ~Container();
    Container(const Container&);
    Container& operator= (const Container&);
    friend ostream& operator<< (ostream&, const Container<T>&); //overloaded container output operator

    void Insert(const T);

    Iterator Begin() const;
    Iterator End() const;  
};

//implementation of container << operator
template<class T>
ostream& operator<< (ostream& os, const Container<T>& c) {

    os << "(";
    typename Container<T>::Node*n = c.first;

    for(; n !=0; n=n->next)
        os << *n <<" ";
    os<<")"<<endl;
    return os;
}

//implementation of node << operator
template<class T>
ostream& operator<< (ostream& os, const typename Container<T>::Node& n) {
    os << n->info;
    return os;
}



main.cpp file
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
#include<forward_list>
#include<container.h>
using std::cout;
using std::endl;
int main()
{
    Container<int> test;
    test.Insert(1);
    test.Insert(2);
    Container<int>::Iterator it;

    for(it = test.Begin(); it != test.End(); it++)
    {
        cout<< *it <<endl; // <-- Compiler saying "undefined reference to operator <<"
    }

//My aim is to make the container to work like STL's one

    std::forward_list<int> az;
    az.push_front(2);
    az.push_front(3);
    std::forward_list<int>::iterator itl = az.begin();
    for(; itl != az.end(); itl++)
        cout<< *itl <<endl;
}


Honestly I can't really understand why the compiler is telling me that, since both the output operator were overloaded, both in container and in node.

Can someone please explain me what I am doing wrong?

Thank you in advance.
Iterator::operator* should return info, not the Node itself. (Does forward_list return an enigmatic "node" object or the object that it stores in a node?)
Thank you very much dutch, fixing it in the way you said solved the problem!

I understood what you meant (your example was very clear) but there is still a thing that I can't grasp:

The returned object was a Node because I thought the compiler would have reasoned in this way:

1
2
3
4
5
6
7
for(it = test.Begin(); it != test.End(); it++)
    {
        cout<< *it <<endl; // dereferencing the Iterator object with operator* returns me a Node
                           // which will be handled by the overloaded output operator in the 
                           // Node class. That operator will access the info field of the node
                           // and will output it in the ostream which will then be returned
    }
Topic archived. No new replies allowed.