Function template overload
It is not surprise that function template also has the overloading ability Let’s first see some examples that shows how the overloading happens.
template <typename Type>
class Array {
/* ... */
public:
Array(int initialvalue) {}
Type operator [](int index) {typename Type value; return value; }
} ;
// there are three templates function definition of min()
template <typename Type>
Type min(const Array<Type>&, int); // #1
template <typename Type>
Type min(const Type*, int); // #2
template <typename Type>
Type min(Type, Type); // #3
And this is the main method which uses it
int _tmain(int argc, _TCHAR* argv[])
{
int i = max(10, 5); // this will instantiate the generic function template
// call to explict specialiation
// const char * max<const char *> (const char *, const char *);
const char * p= max("hello", "world");
cout << "i: " << i << " p: " << p << endl;
return 0;
}
So, as you can see, if the type argument deduction is successful without ambiguity, then the overloading is said to be fine.
But be careful when doing the function overloading. E.g.
Suppose you have the following function template.
/**
* the code below may not be relevant to workable min method, it is just written down here to help understanding of metod
*/
template <typename T>
T min5(T, T) ; // # added here to show the following code snippet may fail
And you have the following code
int TestTemplateAfterMin_T_T()
{
int i;
unsigned int ui;
// type dedcued to int
min5(1024, i);
// template argument deduction fails:
// two different types deduced for T
min5(i, ui);
}
To solve the problem of the failing statement, you may try this:
/**
* You may introduce the declaration of min5(T, U), but it may cause ambiguity for other types
*/
template <typename T, typename U>
T min5(T, U) ; // # added here to but call to min5(1024, i) may fail
However, the first call to min5(1024, i); is now at least suspicious;
Because now
int TestTemplateAfterMin_T_U()
{
int i;
unsigned int ui;
// some compiler may flag it as error
// but vc++ 11 does not complain it as error
// I think it is because min5(T, T) is more specialized than min5(T, U)
// and when two template function is candidates, the more generalized one will win
min5(1024, i); // -> min(T, T);
// template argument deduction fails:
// two different types deduced for T
min5(i, ui); // -> min(T, U)
return 0;
}
Some books think it full in ambiguity; however, as according to my test on VC 11, it is fine, the reason is the so called most specialized; however, this type of overloading should draw someone’s caution/attention;
Below is a more canonical example of the most specialized
/**
* @NOTE:
* the rule of the most specialized - in situation of more than one candidates are availabe, the template with the most specialized
* will be choosen
*/
template <typename Type>
Type sum(Type*, int);
template <typename Type>
Type sum(Type, int);
template <typename Type>
Type sum(Type*, int)
{
using std::cout;
using std::endl;
cout << " sum(Type*, int)" << endl;
Type t;
return t;
}
template <typename Type>
Type sum(Type, int)
{
using std::cout;
using std::endl;
cout << " sum(Type, int)" << endl;
Type t;
return t;
}
int TestTheMostSpecialized()
{
int ia[1024];
// Type == int: sum<int>(int *, int); or
// Type == int*: sum<int *>(int *, int); or ???
int ival1 = sum(ia, 1024);
return 0;
}
The test shows that the sum(Type*, int) wins, because pointer type are more specialized than its non-pointer type.