I have a strange problem. On Windows, with Visual Studio 2010 and also with the Intel Compiler everything is linked as expected. But when I try to compile my code with CLang 3.0 on Linux, it does compile (and if I only use a single CPP file it does also link and run) but does not link.
The message is that there are multiple symbol definitions, referring to template instanciations. For example consider the following two lines in a header file shared across multiple compilation units:
template<class T> void myFunc(T in) { }
template<> void myFunc<int>(int in) { }
Now from the Linux linker I would get something along the lines of:
"file xyz": Multiple definition of "myFunc(int in)", first defined in "some file".
But how would I prevent that? Since it works on Windows I suppose it should work on Linux too somehow?
The same goes for static template data members, which are more or less the same as above just that you declare a variable instead of a function. I would prefer if it worked for static template data members.
If everything else fails I suppose I could still create a "MakeAll.cpp" file which just includes all CPP there are, but that doesn't sound like a desirable solution to me...
Thanks for your help!
In my understanding, you are in fact defining your template specializations multiple times, and this should also give you an error for Windows compilers.
In your header file you are defining a function by providing a body:
template<> void myFunc<int>(int in) { }
This definition will exist in multiple compilation units and the linker should complain.
The same rules apply for your template specialization as for ordinary non-template functions: Either use inline
or use a separate declaration and definition, by putting
template<> void myFunc<int>(int in);
in a header and
template<> void myFunc<int>(int in)
{
// ...
}
in a .cpp
file.
Templates are instantiated by the compiler, and it is the compilers responsibility to make sure that they are only defined once.
When you fully specialize a function, it is not a template anymore (but an ordinary function), and it is your responsibility to make sure it is not multiply defined.
There is very little difference between these functions
template<>
void f<int>(int x)
{ }
void f(int x)
{ }
when it comes to the one definition rule.
Adding inline
helps in both cases.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With