Not sure what it is that I'm doing wrong with templates in this case
Hi, I'm having a weird problem with templates. Here is the linker error that I'm getting (in bold):
Code:
% make clean && time make
rm -rf *o main
g++ -c -g generic-stack.cpp
g++ -c -g main.cpp
g++ -c -g stack.cpp
g++ -c -g enhanced-stack.cpp
g++ -c -g base-stack.cpp
g++ -c -g array-stack.cpp
g++ -c -g list-stack.cpp
g++ main.o generic-stack.o stack.o enhanced-stack.o base-stack.o array-stack.o list-stack.o -o main
Undefined symbols for architecture x86_64:
"GENERIC_STACK<int>::GENERIC_STACK()", referenced from:
_main in main.o
"GENERIC_STACK<int>::~GENERIC_STACK()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [main] Error 1
Here is the header file:
Code:
#ifndef GENERIC_STACK_HPP
#define GENERIC_STACK_HPP
#include "global-includes.hpp"
template <typename T>
class GENERIC_STACK
{
public:
GENERIC_STACK();
~GENERIC_STACK();
void Push(T value);
T Pop();
bool Is_Empty();
private:
protected:
struct NODE
{
T value;
NODE * link;
};
NODE * Head;
};
#endif
Here is a source file:
Code:
#include "generic-stack.hpp"
template <typename T>
GENERIC_STACK<T>::GENERIC_STACK()
{
Head = NULL;
}
template <typename T>
GENERIC_STACK<T>::~GENERIC_STACK()
{
T value;
while(!Is_Empty())
{
Pop(value);
}
}
template <typename T>
void GENERIC_STACK<T>::Push(T value)
{
NODE * temp = new NODE;
temp->value = value;
temp->link = Head;
Head = temp;
}
template <typename T>
T GENERIC_STACK<T>::Pop()
{
T value;
NODE * temp = Head;
value = Head->value;
Head = Head->link;
delete temp;
}
template <typename T>
bool GENERIC_STACK<T>::Is_Empty()
{
return Head == NULL;
}
This is the main method:
Code:
#include "new-stack.hpp"
#include "list-stack.hpp"
#include "array-stack.hpp"
#include "generic-stack.hpp"
int main(int argc, char * argv[])
{
...
GENERIC_STACK<int> int_stack;
return 0;
}
Two things I'd like to add:
1 - I know that standards-wise, this code is ugly. This is just my temporary thing that I'm using to remember about C++.
2 - "global-includes.hpp" includes stuff like #include <iostream>, etc.
Now, my question, why am I getting this ugly error? I've checked my Makefile and that looks good (below) and I don't understand why this is happening.
Makefile
Code:
all: main
main: generic-stack.o main.o stack.o enhanced-stack.o base-stack.o array-stack.o list-stack.o
g++ main.o generic-stack.o stack.o enhanced-stack.o base-stack.o array-stack.o list-stack.o -o main
generic-stack.o: generic-stack.cpp
g++ -c -g generic-stack.cpp
base-stack.o: base-stack.cpp
g++ -c -g base-stack.cpp
array-stack.o: array-stack.cpp
g++ -c -g array-stack.cpp
list-stack.o: list-stack.cpp
g++ -c -g list-stack.cpp
stack.o: stack.cpp
g++ -c -g stack.cpp
enhanced-stack.o: enhanced-stack.cpp
g++ -c -g enhanced-stack.cpp
new-stack.o: new-stack.cpp
g++ -c -g new-stack.cpp
main.o: main.cpp
g++ -c -g main.cpp
clean:
rm -rf *o main
Thoughts?
Yes, I googled, no I could not find an answer that helped me.
Re: Not sure what it is that I'm doing wrong with templates in this case
The template implementation must be visible at the time of instantiation. This is the case for almost every single compiler out there.
What you did was separate the implementation from the interface, and then compiled the implementation into separate modules. This is not correct. You must include the implementation with the interface. If you want an example, open up the <vector> or <list> file and see how these classes are implemented. You will see the entire code is within the header.
So either place the code inline into the template class, or #include the implementation at the end of your .h files. In any event, you also have to make sure you do not compile separate template modules as you're doing now. They are not separable compilation units.
As far as not finding things on google -- there must be thousands of easily found links saying this about templates. Here is one right here on this board:
http://forums.codeguru.com/showthrea...-template-code
Here are more links:
http://www.parashift.com/c++-faq/tem...n-vs-decl.html
http://www.parashift.com/c++-faq/sep...from-decl.html
http://www.parashift.com/c++-faq/sep...t-keyword.html
In addition, there have countless threads with the same question concerning templates, all answered in the same way (which is why a FAQ was created for this years ago).
Regards,
Paul McKenzie