Operators >> and <<

Hello! I'm trying to redefine the >> and << operators. Everything is working well when I try to do it with ordinary data structures. The problem comes when I try to use a template.

1
2
ostream& operator<<(ostream& ostr, Stack<T>& stack);
istream& operator>>(istream& istr, Stack<T>& stack);


The compiler says that I can't define Stack<T>& stack;
Can somebody tell me how can I solve this problem?

Greetings!
Try...
1
2
3
4
template <typename  T>
ostream& operator<<(ostream& ostr, Stack<T>& stack);
template <typename  T>
istream& operator>>(istream& ostr, Stack<T>& stack);


(Yes, you just needed to add template <typename T> before declaration)
Oh, I have forgot to say that I have template<class T> in my code. I changed it to template<typename T> but it still prints the same error:

code.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Stack<int> &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@AAV?$Stack@H@@@Z) referenced in function _main
That's a linking error, your code actually compiled. I can only guess that you placed the definition of those operators in some source file instead of the header.
Everything is in one .cpp file. The program doesn't even run because of this error...
Here is my whole code if you want to see it:
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
#include<iostream>
#include<iomanip>
using namespace std;

template<class T>
struct Node
	{
		T data;
		Node<T> *next;
	};

template<typename T>
class Stack
	{
	private:
		Node<T> *top;
	public:
		Stack();
		void Push(T);
		void Pop();
		void Print_Stack(ostream&);
		friend istream& operator>>(istream&, Stack<T>&);
		friend ostream& operator<<(ostream&, Stack<T>&);
	};

template<typename T>
istream& operator>>(istream& istr, Stack<T> &stack)
	{
		T data;
		istr >> data;
		stack.Push(data);
		return istr;
	}

template<typename T>
ostream& operator<<(ostream& ostr, Stack<T> &stack)
	{
		stack.Print_Stack(ostr);
		return ostr;
	}

template<typename T>
Stack<T>::Stack()
	{
		top = NULL;
	}

template<typename T>
void Stack<T>::Push(T data)
	{
		Node<T> *temp = new Node<T>;
		temp->data = data;
		temp->next = top;
		top = temp;
	}

template<typename T>
void Stack<T>::Pop()
	{
		Node<T> *temp = top;
		top = top->next;
		delete temp;
	}

template<typename T>
void Stack<T>::Print_Stack(ostream& ostr)
	{
		Node<T> *temp = top;
		while(temp)
			{
				ostr << temp->data << " ";
				Pop();
				temp = top;
			}
		cout << endl;
	}



int main()
	{
		Stack<int> A;
		cin >> A;
		cin >> A;
		cin >> A;

		cout << A;

		system("pause");
		return 0;
	}
1
2
friend istream& operator>>(istream&, Stack<T>&);
friend ostream& operator<<(ostream&, Stack<T>&);


here is your problem

because you define >> or << as friend you must type template for it

[sorry for my english]

like this
1
2
template<tType> friend istream& operator>>(istream&, Stack<T>&);
template<tType> friend ostream& operator<<(ostream&, Stack<T>&);


template parameter must have different name with your stack class
A better solution is to define them inline:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
template<typename T>
class Stack
{
    //...
public:
    //...
    //...

    friend istream &operator>>(istream &is, Stack &s)
    {
        //...
        return is;
    }
    friend ostream &operator<<(ostream &os, Stack &s)
    {
        //...
        return os;
    }
};
@L B: A better solution is to define them inline

Thanks a lot! That helped. Can you tell me why defining them outside the class is not working?
Because you're using templates.
As templates must be compiled in a different way, they must go in the header file.
If you want them in the source file, it's also ok if you declare/define them inside the class.

@LB: Why shouldn't it be Stack<T> ? Is that a typo? (@lines 9 and 14)
Last edited on
@EssGeEich
I tried both Stack and Stack<T>. Both ways work. :)

And so you are telling me that if the whole code except the main() function was in a header file it would work to define them outside the class? I will try :)
Last edited on
All about what's templated should go into headers.
If it's a function or a nontemplate class, it should have source files.

In fact main is a nontemplated function, and as such, it requires to be in a source file.
Last edited on
template friends are a little tricky to get right - the C++ FAQ has an entry on them: http://www.parashift.com/c++-faq/template-friends.html

Do they need to be friends in your case?
Last edited on
Thanks for the great link :)
If they are not friends the compiler shows another error message.
Last edited on
I actually did this same thing about an hour ago for another guy:
http://www.cplusplus.com/forum/general/110656/2/#msg604391
Topic archived. No new replies allowed.