I have the following code:
//1
template<typename T>
void c(T in) {
cout << "Template c(" << in << ")" << endl;
}
//2
template<>
void c<>(int* in) {
cout << "Template specialization b(" << in << ")" <<endl;
}
//3
template<typename T>
void c(T* in) {
cout << "Template for pointers c(" << in << ")" <<endl;
}
//..
int i = 8;
c(&i);
Can someone explain me why in the following example compiler choose function #3, but when I change the order of functions #2 and #3, then compiler choose function #2?
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
You can choose to specialize only some of the parameters of a class template. This is known as partial specialization. Note that function templates cannot be partially specialized; use overloading to achieve the same effect.
A function definition can only be provided once in a given program (unless the function is marked inline ). A function template can be defined in multiple translation units, and the linker will pick one copy of each actual instantiation.
Advantages of Using Templates in C++ Templates are type-safe. They are generally considered as an improvement over macros for these purposes. Templates avoid some common errors found in code that make heavy use of function-like macros. Both templates and macros are expanded at compile time.
The compiler first chooses the primary template and only then determines which specialization to use. That is, in your case the compiler always chooses the second primary template, i.e., #3.
However, since you didn't specify the template argument when specializing the function template, your specialization specializes a different primary template depending on its location: with the given order, it specializes the first primary template, when you exchange the order of #2 and #3 it specializes the the second primary template. In 14.7.3 [temp.expl.spec] paragraph 7 the standard has to say the following about the situation
... When writing a specialization, be careful about its location; or to make it compile will be such a trial as to kindle its self-immolation.
If you wanted to control which primary template the specialization actually specializes, you would specify the template arguments in the specialization:
template <> void c<int*>(int* in) { ... } // specializes the first primary
template <> void c<int>(int* in) { ... } // specializes the second primary
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