Reputation: 109
A: I use something like this:
In Class1.h:
template <class T>
class Class1 : Database {
public:
Class1();
};
In Class1.cpp:
#include "Class1.h"
template <typename T>
Class1<T>::Class1(){
//Some code
}
Calling class:
#include "Class1.h"
Class1<Class2> *class1 = new Class1<Class2>();
If i run this, the linker is not able to find "Class1".
B: When i use something like this:
#include "Class1.h"
template <> Class1<Class2>::Class1(){}
The linker is able to find it.
My problem is, that i need to use A in my code and not B.
That means i don't want to use:
template <> Class1<Class2>::Class1(){}
I Want to use ONLY:
template <typename T>
Class1<T>::Class1(){
//Some code
}
All tutorials say that i use it correctly and it has to work. Can anybody help me?
Upvotes: 1
Views: 143
Reputation: 6086
When you try to instantiate a specialization of a class template, the compiler needs to have access to every member definition, otherwise it is unable to generate the corresponding code (a C++ template is basically a copypasta factory on steroids).
Since you split the implementation details into a separate file, you cannot instantiate your specific specialization a.k.a. Class1<Class2>
. I suppose you put the template <> Class1<Class2>::Class1() {}
bit in the header file? If so, your code compiles because it has a full specialization for Class2
with an available constructor when you use it in your sample.
Schematically you have:
Template Header -> included in -> test sample cpp file
\-----------------------> included in -> Template Implementation cpp file
You can see that all the actual implementations for your template are not reachable within your test sample translation unit.
Upvotes: 6
Reputation: 66190
As said in comments, Class1
is a templated class, so you should put you contructor in the header file, not in a separated cpp file.
Otherwise, you can put the constructor in the cpp file where you use it, but only if you use it only in a single cpp file.
The problem is that when you write
Class1<Class2> *class1 = new Class1<Class2>();
you're asking the compiler to call (and construct) a constructor for Class1<Class2>
but the compiler don't know how to construct it because it's defined in another file (the compiler, in this phase, see only "Class1.h"; doesn't know the content of "Class1.cpp").
Your solution B
template <> Class1<Class2>::Class1(){}
works because you're defining a constructor specialization for Class1<Class2>
, so the compiler know it
Solution: delete
template <typename T>
Class1<T>::Class1(){
//Some code
}
from "Class1.cpp" and put it in "Class1.h".
p.s.: sorry for my bad English.
Upvotes: 1