Issue with class templates

Hi, i am quite new to template programming, and i am getting the Error "LNK2019 unresolved external symbol "public: int __thiscall LStack<int>::push(int)" (?push@?$LStack@H@@QAEHH@Z) referenced in function _main Data_Structures 1"

Can someone kindly shed some light on where i am messing up the linkage in the push() method.?


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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
////.h file
#pragma once
#define NULL 0

template <typename T>
struct stackNode
{
	T element;
	stackNode* nxt;
	stackNode* last;

};

template <typename C>
class LStack
{
private:
	stackNode<C>* firstNode;
	int size;
	stackNode<C>* lastNode;
	bool stackFull;
	bool stackEmpty;
public:

	LStack(int sz)
	{
		stackFull = false;
		stackEmpty = true;
		size = sz;
		firstNode = new stackNode<C>();
		firstNode->element = NULL;
		firstNode->last = nullptr;
		stackNode<C>* tempNode;
		tempNode = firstNode;
		tempNode->nxt = new stackNode<C>();
		tempNode = tempNode->nxt;
		tempNode->last = firstNode;
		for (int i = 1; i < size; i++)
		{
			tempNode->nxt = new stackNode<C>();
			tempNode = tempNode->nxt;
			tempNode->last = tempNode;
		}
		lastNode = tempNode;
		lastNode->last = tempNode;
		lastNode->nxt = nullptr;
	}

	~LStack()
	{
		stackNode<C>* tempNode;
		tempNode = firstNode->nxt;
		delete firstNode;
		firstNode = nullptr;
		while (tempNode->nxt != nullptr)
		{	
			firstNode = tempNode;
			tempNode = tempNode->nxt;
			firstNode->nxt = nullptr;
			firstNode->last = nullptr;
			delete firstNode;
			firstNode = nullptr;
		}
		tempNode->last = nullptr;
		tempNode->nxt = nullptr;
		delete tempNode;
		tempNode = nullptr;
		delete lastNode;
		lastNode = nullptr;
	}

	int push(C elem);
	C pop();
	//int search(C& element);


};
//////////////////////////////////
//////////.cpp file
#include "LStack.h"
#include <iostream>
using namespace std;

template <typename C>
int LStack<C>::push(C elem)
{
	stackNode<C>* tempNode;
	tempNode = lastNode;

	if (stackEmpty != false)
	{
		stackEmpty = false;
	}

	if (stackFull == true)
	{
		cout << "..Err..Stack is full..!! Consider resizing." << endl;
		return -1;

	}

	while (tempNode != firstNode)
	{
		if (tempNode->element == NULL)
		{
			tempNode->element = elem;
		}
		else
		{
			tempNode = tempNode->last;
		}

	}
	if (tempNode == firstNode)
	{
		stackFull = true;
	}
	return 1;
}


template <typename C>
C LStack<C>::pop()
{
	C elem = firstNode->element;
	if (stackEmpty == true)
	{
		cout << "..Err..Stack is empty..!!" << endl;
		return elem;
	}
	else
	{
		cout <<"Popping out top element from stack"<< firstNode->element << endl;
		stackNode<C>* tempNode;
		tempNode = firstNode->next;
		delete firstNode;
		firstNode = nullptr;
		firstNode = tempNode;
		firstNode->last = nullptr;
		return elem;
	}
}
////////////////////////////////
///////////////main file
#include <iostream>
using namespace std;
#include "LStack.h"

int main()
{
	LStack<int> stk(5);
	cout << "In main File" << endl;
	stk.push(1);


	return 1;
}

  Put the code you need help with here.
At using templated code you cannot split this templated code into declaration and definition parts. That's because both parts will be needed for creating the correct type, but the compiler compiles all *.cpp parts as separate units.

At your example, the compiler doesn't know at compiling your LStack.cpp which type you will use in your main.cpp file. At main.cpp you define LStack<int>, but the compiler doesn't know this information when it compiles LStack.cpp. And in consequence, the linker fails to link both parts together.
Template implementations are not really cpp files since they can't be compiled until the type information is supplied. One option is to simply add the implementations to the end of the .h file. If you must have them in a separate file, call it a .tpp (or .ipp) file and include it at the end of the .h file.
Thank you both..!
Topic archived. No new replies allowed.