Reputation: 9442
If I have a template function in a seperate compile unit (which produces an object file with suffix .o from the CUDA C compiler NVCC)
lets say we have the definition (implementation)
template<typename T>
void foo(T a){
// something
}
To produce the explicit code in the object file to be able to link to it from another compilation unit I need to explicit instantiate this template (for all template parameters I need) this:
template void foo<double>(double a);
template void foo<float>(double a);
Doing this results in actual code in the object file.
Doing the other thing like:
template<> void foo<double>(double a);
template<> void foo<float>(float a);
Does not produce code in the object file, because this is a full spezialized template declaration. Is this correct?
Also
void foo(double a);
void foo(float a);
does not produce code because this would be a overload declaration ? is this correct?
The question is now, what is the general syntax to make the compiler produce code for a template function or class in a separate compilation unit?
Upvotes: 2
Views: 588
Reputation: 37975
In laymans terms, when you write this:
template void foo<double>(double a);
template void foo<float>(double a);
You are explicitly telling the compiler to instantiate the function template with the correct template arguments, so you get an implementation of foo<double>
and foo<float>
just as if you had copy pasted the code from the function template and replaced T
with double
and float
.
On the other hand, when you write this:
template<> void foo<double>(double a);
template<> void foo<float>(float a);
You are telling the compiler that foo<double>
and foo<float>
are completely different things that have no relation whatsoever with foo<T>
. This is called specialization. However, you are not providing a definition for these specializations, only declarations: you are merely telling the compiler that these things exist, but not what they are. A definition of a specialization would look like this:
template<>
void foo<double>(double a) {
// something else
}
Depending on your intent, you may want to either:
foo<double>
and foo<float>
share the same implementation)I am guessing you want the first.
Upvotes: 3