Reputation: 634
Newbie to C++ so please forgive me. I'm trying to write a simple template class to implement the Stack data structure functionality. I've read through this question to understand how template declaration and implementation works: Why can templates only be implemented in the header file?. But I would like to use the solution where class declaration and implementation are separate (not defined inline in .h).
MyStack.h:
#include "StackNode.h"
#include "MyStack.tpp"
template <typename T>
class MyStack
{
private:
StackNode<T> *top;
public:
MyStack();
virtual ~MyStack();
};
MyStack.tpp:
#include "MyStack.h"
template <typename T>
MyStack<T>::MyStack()
: top(nullptr)
{
}
template <typename T>
MyStack<T>::~MyStack()
{
}
main.cpp:
#include "MyStack.h"
int main() {
MyStack<int> myStack;
return 0;
}
However compiling the above gives this error:
../src/MyStack.tpp:11:1: error: 'MyStack' does not name a type
../src/MyStack.tpp:18:1: error: 'MyStack' does not name a type
I know I'm missing something, but don't understand what. Thanks!
Upvotes: 3
Views: 3839
Reputation: 596266
The problem is that you are including the .tpp
file, which contains the class method definitions, before the class has actually been declared yet. You need to move that #include
statement below the class declaration instead.
Also, the .tpp
file should not be #include
'ing the .h
file that originally #include
'd it. In fact, that won't work correctly since your .h
file is missing header guards to prevent multiple inclusions within the same translation unit (ie, main.cpp
in this case). So, you would end up with MyStack.h
which includes MyStack.tpp
which includes MyStack.h
again, which causes an error when it tries to re-declare things that are already declared. Always declare a header guard in your .h
files.
Try this instead:
MyStack.h:
#ifndef MyStack_H
#define MyStack_H
#include "StackNode.h"
template <typename T>
class MyStack
{
private:
StackNode<T> *top;
public:
MyStack();
virtual ~MyStack();
};
#include "MyStack.tpp"
#endif
MyStack.tpp:
template <typename T>
MyStack<T>::MyStack()
: top(nullptr)
{
}
template <typename T>
MyStack<T>::~MyStack()
{
}
Upvotes: 4