?
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.
?
?