g++ issue

Hey there,

I'm trying to compile the following "project" of 2 source files and one header using g++:
Source: MyStack.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
#ifndef MYSTACK_H
#define MYSTACK_H

template <typename T>
class MyStack {
public:
	MyStack(int = 10);

	~MyStack();

	bool push(const T&);

	bool pop(T&);

	bool isEmpty() const;

	bool isFull() const;

private:
	int size;
	int topIndex;
	T *top;
};

#endif 


Source: MyStack.cpp
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
#include "MyStack.h"

template <typename T>
MyStack<T>::MyStack(int size) {
	this->top 		 = new T[(size > 0) ? size : 10];
	this->size		 = size;
	this->topIndex	 = -1;
}

template <typename T>
MyStack<T>::~MyStack() {
	delete[] this->top;
}

template <typename T>
bool MyStack<T>::push(const T &item) {
	if(this->isFull()) {
		T *newStack = new T[(this->size *= 2)];
		
		for(int i = 0;i < this->size;i++) {
			newStack[i] = this->top[i];
		}

		delete[] this->top;
		this->top = newStack;
	}

	this->top[++this->topIndex] = item;

	return true;
}

template <typename T>
bool MyStack<T>::pop(T &item) {
	if(this->isEmpty()) {
		item = this->top[this->topIndex--];

		return true;
	}

	return false;
}

template <typename T>
bool MyStack<T>::isEmpty() const {
	return this->topIndex == -1;
}

template <typename T>
bool MyStack<T>::isFull() const {
	return this->topIndex == this->size;
}


Source: Main.cpp
1
2
3
4
5
6
7
8
9
10
#include "MyStack.h"
#include <iostream>
using namespace std;

int main() {
	MyStack<int> intStack(3);
	int intValue;

	return 0;
}


and I'm getting the following linker error:
1
2
3
4
5
$ g++ -o MyStack Main.cpp MyStack.cpp
/tmp/ccnksMQn.o: In function `main':
Main.cpp:(.text+0x16): undefined reference to `MyStack<int>::MyStack(int)'
Main.cpp:(.text+0x27): undefined reference to `MyStack<int>::~MyStack()'
collect2: ld returned 1 exit status 


Does someone see what did I do wrong?
closed account (1yR4jE8b)
Put your code for MyStack.cpp into the header file.
Is it the only way to solve this issue?
Actually I was fighting to find a way I didn't have to combine both of them in a single file.
You can rename MyStack.cpp to have an extension that the compiler won't compile automatically and #include it at the end of the header if you want to keep it in another file
Is it a kind of issue with templates? Because I can normally compile any other kind of code this way.
Yes
Good to know. Thank you Bazzy.
closed account (1yR4jE8b)
Let me and try and explain the reason this happens:

The compiler only generates code for template classes/functions when they are called explicitly. So when you try to compile your MyStack.cpp file, the compiler doesn't see any calls to the functions so it simply ignores the definitions and generates an empty object file.

When you try to link that object file with your main.cpp file, the function definitions were not compiled so the linker cannot link the calls to function code. Hence the undefined reference errors from the linker.

This is why the definitions for template code must be in the header files.
Topic archived. No new replies allowed.