Reputation: 11
Hi everybody I just wanted to practice some c++ template but i get linker errors. Can anybody help me please? Here is my code:
// File: MyClass.h
#ifndef _MYCLASS_H
#define _MYCLASS_H
template<class T> class MyClass {
T value;
public:
MyClass(T v);
~MyClass();
};
#endif // _MYCLASS_H
// File: MyClass.cpp
#include "MyClass.h"
template<class T> MyClass<T>::MyClass(T v) {
value = v;
}
template<class T> MyClass<T>::~MyClass() {
}
// File: main.cpp
#include "MyClass.h"
int main() {
MyClass<int> test(10);
return 0;
}
Here is command line output:
g++ main.cpp -c
g++ MyClass.cpp -c
g++ main.o MyClass.o -o Out
main.o: In function `main':
main.cpp:(.text+0x1a): undefined reference to `MyClass<int>::MyClass(int)'
main.cpp:(.text+0x2b): undefined reference to `MyClass<int>::~MyClass()'
collect2: ld returned 1 exit status
make: *** [all] Error 1
As you can see I'm using Ubuntu 10.04 and GNU C++ Compiler. Am I missing something in this code?
Thanks for replies. It works but isn't there a better way to protect the code? For example what if I want to create a non-opensource library?! I want to export the code to a static library. and link the library to other projects ...
Upvotes: 1
Views: 709
Reputation: 6887
@Nikolai N Fetissov has the right solution. I would add to this that a nice way to do this, if you want to keep the implementation and templated function definitions separate is that you can put the implementations into MyClass.hxx
and include it at the end of your MyClass.h
// File: MyClass.h
#ifndef _MYCLASS_H
#define _MYCLASS_H
template<class T> class MyClass
{
T value;
public:
MyClass(T v);
~MyClass();
};
#include "MyClass.hxx" /// <--- like this
#endif // _MYCLASS_H
Upvotes: 1
Reputation: 8805
It's important to remember what a template is. It is a template for generating code if needed; it is not code itself.
So declaring a template class and writing implementations for those methods does not generate any object code for that class; it simply provides a template for doing so if necessary.
When a template class is instantiated with an actual argument, the compiler will generate the code from the template class. In order to do that, it needs to be able to see the the templates. But since you've only #include
ed the .h file, and the implementation of the methods in in the .cpp file, the compiler won't be able to generate the object code for the function implementations. Then, when the linker looks for those definitions it won't find it.
All of this is a long-winded way of getting to the same result the other answers did -- you need to put the implementation in the header file with the class declaration. But it may help to know why that is.
Upvotes: 0
Reputation: 1724
You should put template classes and inline methods into header files. You can't seperate definition and implementation in their case.
Upvotes: 1
Reputation: 84151
You have to put full template into the header. Compiler needs to see the body of the template methods at the site of template instantiation - main.cpp
in your case. See, for example, C++ FAQ.
Upvotes: 5