But there is partial specialization as well, right?
No. It is not a specialization. It is just another function which has an overloaded name that happens to be a template.
This more clearly demonstrates partial specialization
(I know you are being helpful so I will do my best to avoid any snark. If you see any, it is accidental; I intend no offense.)
No. That is not partial specialization.
Why? There is no template on which the function you think to be a partial specialization depends.
Code:
template <typename T> class Test{};
template <typename T> class Test<T*>{};
The second line, the partial specialization, depends on the first line, the original template, to "function".
That is partial specialization.
What you have for your second function, the one you think is partially specialized, is just an overloaded function.
Simply put, you can't directly partially specialize a function template; you will always either get a specialized template or just another template function.
The function in question, the second one, is just a template which takes an `int' first parameter and a generic second parameter.
The third function is a specialization. Here it is a specialization of the second function. If you were to remove the second function from your example is would become a specialization for the first template. If you remove both, it will not compile because it is a specialization that depends on an original template.
This bring us to the first "tip": when it comes to functions, if you don't have `template<>' you don't have a specialization.
Before we move on, we need another example. I'm going to borrow from the one Shakti posted.
Code:
#include <iostream>
template<typename T, typename U>
void Func(T t, U u)
{
std::cout << "Fully generic" << std::endl;
}
template<>
void Func(int t, int u)
{
std::cout << "Fully specialized for int" << std::endl;
}
template<typename U>
void Func(int t, U u)
{
std::cout << "Partially specialized for int" << std::endl;
}
int main()
{
Func(10.0, 10.0);
Func(10, 10.0);
Func(10, 10);
}
I only moved the third function, a specialized template, above the second function forcing it to be a specialization of the first function.
What is the problem?
Code:
Fully generic
Partially specialized for int
Partially specialized for int
The output isn't what you thought it would be, is it?
The second function, originally the third, isn't considered at all by the compiler. The compiler only looks at the other two template functions for overload resolution. It sees that the third function, originally the second, is more appropriate and so chooses it. That function has no specializations so the compiler stops looking and just uses that function.
In the original, the compiler still looks at the same two templates for overload resolution. The only difference, seen because in the original the third function was a specialization of the second, the second function which is a better match has a specialization which the compiler will look through because the "base" template was chosen during overload resolution.
This bring me to my second "tip": specialization do not participate in overload resolution the same as simple functions and function templates.
Before we continue, we need another example, only this time, I'm going to use the same code Shakti posted.
How is this example different? Let's put our two template functions and the specialization (the three functions named `Func') in a header so we can reuse them in all their glory.
So, we now have three files in our project: "func.h", "main.cpp", and "more.cpp".
For the sake of simplicity, let's just assume both "main.cpp" and "more.cpp" call all three functions.
Now, let's link our code into a binary application.
Failure!
So, what's the problem?
We got a linker error because specialized template functions are not templates. (You: What?)
It is a complicated mess, and I'm not going to go into why this behavior is necessary (Yes, believe it or not, all of the behavior related to templates functions discussed here it to be preferred), but the simple view is: template function specializations are templates, but not overloads, to a compiler and functions, but not templates, to a linker.
Why is this all so complicated? There are reasons; you'll just have to either research yourself or take my word for it.
Fortunately, it simply does not have to be so complicated for almost all cases.
How do you avoid this complexity?
This bring us to the third "tip": don't specialize template functions.
You will almost never want a specialized template function.
Instead of trying to specialize a template function, just overload the function as you would normally optionally marking it `inline', and possible `static', if you want to include the source in headers with your templates functions.
Why? It solves all of our problems which I've discussed. (For example, it would not matter where you put the third function, second in my example, if it was just a function because it would participate in overload resolution.)
You are now free to enjoy your newly discovered "OH. MY. GOD! WHY IS C++ SO COMPLICATED!?" because I'm done discussing this... for now.
Mwhahahahaha!
Soma