I am getting errors trying to compile a C++ template class which is split between a .hpp
and .cpp
file:
$ g++ -c -o main.o main.cpp
The place where you might want to do this is when you create a library and header combination, and hide the implementation to the user. Therefore, the suggested approach is to use explicit instantiation, because you know what your software is expected to deliver, and you can hide the implementations.
Some useful information is here: https://docs.microsoft.com/en-us/cpp/cpp/explicit-instantiation?view=vs-2019
For your same example: Stack.hpp
template
class Stack {
public:
Stack();
~Stack();
void Push(T val);
T Pop();
private:
T val;
};
template class Stack;
stack.cpp
#include
#include "Stack.hpp"
using namespace std;
template
void Stack::Push(T val) {
cout << "Pushing Value " << endl;
this->val = val;
}
template
T Stack::Pop() {
cout << "Popping Value " << endl;
return this->val;
}
template Stack::Stack() {
cout << "Construct Stack " << this << endl;
}
template Stack::~Stack() {
cout << "Destruct Stack " << this << endl;
}
main.cpp
#include
using namespace std;
#include "Stack.hpp"
int main() {
Stack s;
s.Push(10);
cout << s.Pop() << endl;
return 0;
}
Output:
> Construct Stack 000000AAC012F8B4
> Pushing Value
> Popping Value
> 10
> Destruct Stack 000000AAC012F8B4
I however don't entirely like this approach, because this allows the application to shoot itself in the foot, by passing incorrect datatypes to the templated class. For instance, in the main function, you can pass other types that can be implicitly converted to int like s.Push(1.2); and that is just bad in my opinion.