The question is pretty simple. Is there any difference between:
template <typename T>
T add(T a, T b)
{
return a + b;
}
template <>
int add<int>(int a, int b)
{
return a + b; //no reason to specialize, but still...
}
And:
template <typename T>
T add(T a, T b)
{
return a + b;
}
int add(int a, int b)
{
return a + b; //no reason to overload, but still...
}
They seem to be the same.
In "simple" cases, they would behave identically, but they are some cases where they differ.
A trivial difference, is the explicit call add<int>
which will call the specialization and not the overload.
Other differences happens for overload resolution, a call like:
add(42, 4.2f);
will fail with the template specialization (int
and float
, so T
cannot be deduced)
whereas, overload is valid and will convert the float
to int
.
It makes no difference in this case, but there are cases where it will. Lets look at this sample code
template<class T> // (a)
void f(T);
template<> // (b)
void f<>(int*);
template<class T> // (c)
void f(T*);
int main()
{
int *p;
f(p);
}
When we call f(p);
, what function would you expect to be called? Most people would go with b
, and they would be wrong. The reason for this is because specializations do not apply to overload resolution. They are a special recipe for a template that tells the compiler that if you deduce this type, then stamp out the template this way instead.
So what the compiler does is go through overload resolution and says I can call a
with T
being int*
, or I can call c
with T
being int
. Since the latter is more specialized (T
is narrower), c
wins. This can be very surprising but it makes a lot of sense once you ignore the specialization and just consider the overloads.
Walter E. Brown has a very in depth video about templates and specialization called “C++ Function Templates: How Do They Really Work?” that you should consider watching. It is an hour long, but it is very detailed.
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