A problem in using template

Hi all, I have a problem using template, the code is behind
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
QueueItem.h

#ifndef QUEUEITEM_H
#define QUEUEITEM_H

template<typename Type> class Queue;
template<typename Type>
class QueueItem
{
	friend Queue<Type>;
private:
	QueueItem(const Type& t) : item(t), next(0) {}

	Type item;
	QueueItem* next;

};

#endif //QUEUEITEM_H 


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
Queue.h

#ifndef QUEUE_H
#define QUEUE_H
#include "QueueItem.h"
template<typename Type>
class Queue
{
public:
	Queue() : head(0), tail(0) {}
	Queue(const Type& Q) : head(0), tail(0)
	{
		copy_elems(Q);
	}
	//Queue& operator=(const Queue&);
	~Queue() {destroy();}

	//Type& front() {return head->item;}
	const Type& front() const {return head->item;}
	void push(const Type&);
	void pop();
	bool empty() const
	{
		return head == 0;
	}
	void show();
private:
	void destroy();
	void copy_elems(const Queue&);
private:
	QueueItem<Type> *head;
	QueueItem<Type> *tail;


};


#endif //QUEUE_H




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
Queue.cpp

#include "Queue.h"
#include <iostream>


template<typename Type>
void Queue<Type>::destroy()
{
	while(!empty())
		pop();
}

template<typename Type>
void Queue<Type>::pop()
{
	QueueItem<Type>* p = head;
	head = head->next;
	delete p;
}

template<typename Type>
void Queue<Type>::push(const Type & val)
{
	QueueItem<Type> *pt = new QueueItem<Type>(val);
	if(empty())
	{
		head = tail = pt;
	}
	else
	{
		tail->next = pt;
		tail = pt;
	}
}

template<typename Type>
void Queue<Type>::copy_elems(const Queue<Type> &val)
{
	for(QueueItem<Type>* pt = val.head; pt; pt = pt->next)
	{
		push(pt->item);
	}
}
template<typename Type>
void Queue<Type>::show()
{
	for(QueueItem<Type>* pt = head; pt; pt = pt->next)
	{
		std::cout << pt->item << std::endl;
	}
}


1
2
3
4
5
6
7
8
9
10
11
GeneralMain.cpp

#include "Queue.h"

int main()
{
	Queue<int> qi;
	qi.push(1);
	qi.push(2);
	qi.show();
}


And there are some errors:
1
2
3
4
eneralMain.obj : error LNK2019: unresolved external symbol "public: void __thiscall Queue<int>::show(void)" (?show@?$Queue@H@@QAEXXZ) referenced in function _main
1>GeneralMain.obj : error LNK2019: unresolved external symbol "public: void __thiscall Queue<int>::push(int const &)" (?push@?$Queue@H@@QAEXABH@Z) referenced in function _main
1>GeneralMain.obj : error LNK2019: unresolved external symbol "private: void __thiscall Queue<int>::destroy(void)" (?destroy@?$Queue@H@@AAEXXZ) referenced in function "public: __thiscall Queue<int>::~Queue<int>(void)" (??1?$Queue@H@@QAE@XZ)
1>I:\Temp2\project\C++\Study\Debug\Study.exe : fatal error LNK1120: 3 unresolved externals


Could some one help me? Thanks
Templated things have to be declared and defined in the same file. In other words, you have to move everything in Queue.cpp to Queue.h.
o, thanks, I fixed it and it run good~~~
Now I have new problem, I try to overload the operator << in my app, and I have a problem, the code is :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
QueueItem.h

#ifndef QUEUEITEM_H
#define QUEUEITEM_H
#include <iostream>
template<typename Type> class Queue;
template<typename Type> std::ostream& operator<< (std::ostream&, const Queue<Type>&);
template<typename Type>
class QueueItem
{
	friend Queue<Type>;
	friend std::ostream& operator<< <Type> (std::ostream& ,const Queue<Type>&);
private:
	QueueItem(const Type& t) : item(t), next(0) {}

	Type item;
	QueueItem* next;

};

#endif //QUEUEITEM_H 



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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
Queue.h

#ifndef QUEUE_H
#define QUEUE_H
#include "QueueItem.h"
#include <iostream>
template<typename Type>
std::ostream& operator<< (std::ostream& os, const Queue<Type> &q)
{
	os << "< ";
	QueueItem<Type> *p;
	for(p = q.head; p; p = p->next)
		os << p->item << " ";
	os >> ">";
	return os;
}

template<typename Type>
class Queue
{
	friend std::ostream&
		operator<< <Type>(std::ostream&, Queue<Type> &);
public:
	Queue() : head(0), tail(0) {}

	template <typename It>
	Queue(It beg, It end) : head(0), tail(0)
	{
		copy_elems(beg, end);
	}

	Queue(const Type& Q) : head(0), tail(0)
	{
		copy_elems(Q);
	}
	Queue& operator=(const Queue&);
	~Queue() {destroy();}

	template<typename It>
	void assign(It, It);

	//Type& front() {return head->item;}
	const Type& front() const {return head->item;}
	void push(const Type&);
	void pop();
	bool empty() const
	{
		return head == 0;
	}
	void show();
private:
	void destroy();
	void copy_elems(const Queue&);
	template <typename It>
	void copy_elems(It, It);
private:
	QueueItem<Type> *head;
	QueueItem<Type> *tail;


};


#include <iostream>




template<typename Type>
Queue<Type>& Queue<Type>::operator =(const Queue<Type>& q)
{
	destroy();
	this->head = q.head;
	this->tail = q.tail;
	return *this;
}


template<typename Type>
void Queue<Type>::destroy()
{
	while(!empty())
		pop();
}

template<typename Type>
void Queue<Type>::pop()
{
	QueueItem<Type>* p = head;
	head = head->next;
	delete p;
}

template<typename Type>
void Queue<Type>::push(const Type & val)
{
	QueueItem<Type> *pt = new QueueItem<Type>(val);
	if(empty())
	{
		head = tail = pt;
	}
	else
	{
		tail->next = pt;
		tail = pt;
	}
}

template<typename Type>
void Queue<Type>::copy_elems(const Queue<Type> &val)
{
	for(QueueItem<Type>* pt = val.head; pt; pt = pt->next)
	{
		push(pt->item);
	}
}

template<typename Type> template <typename It>
void Queue<Type>::copy_elems(It beg, It end)
{
	while(beg != end)
	{
		push(*beg);
		++beg;
	}
}

template<typename Type> template<typename It>
void Queue<Type>::assign(It beg, It end)
{
	destroy();
	copy_elems(beg, end);
}

template<typename Type>
void Queue<Type>::show()
{
	for(QueueItem<Type>* pt = head; pt; pt = pt->next)
	{
		std::cout << pt->item << std::endl;
	}
}

#endif //QUEUE_H


1
2
3
4
5
6
7
8
9
10
11
12
13
14
GeneralMain.cpp

#include "Queue.h"
#include <vector>

int main()
{
	short a[4] = {0, 3, 5, 9};
	Queue<int> qi(a, a + 3);
	std::cout << qi;
	std::vector<int> vi(a, a+ 4);
	qi.assign(vi.begin(), vi.end());
	std::cout << qi;
}


and the error are
1
2
1>GeneralMain.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl <<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Queue<int> &)" (?<<@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@AAV?$Queue@H@@@Z),该符号在函数 _main 中被引用
1>G:\Temp2\project\C++\Study\Debug\Study.exe : fatal error LNK1120: 1 个无法解析的外部命令



sorry, I am at home and the os's language is Chinese, but most likely the errors above,hope help~
I think the first <Type> on line 22 of Queue.h makes it different from the function that begins on line 7.
LNK2019 is "unresolved external symbol 'symbol' referenced in function 'function'"

I'll give you some advice: when you're programming, try to use as many tools as possible in English, particularly if you expect you'll have to ask for help.
No, I'm not anglo-centric -- I'm not even a native speaker -- it's just that English is programming's lingua franca.
Last edited on
Oh yes, I add 'const' before 'Queue' at line 22 and it's ok now,thanks
Topic archived. No new replies allowed.