Templates and generic programming -- instantiation [continued]
Ii. Explicit real parameters of the function Template
In some cases,It is impossible to infer the type of the real parameters of the template.. When the FunctionThe return type must be different from all types used in the form parameter table.This problem occurs most often. In this case, it is necessaryOverwrite template real-parameter Inference Mechanism, AndExplicitly specify the type or value used by the template parameters.
1, Specify the explicit template parameters
If the types of function parameters are different, how do I specify the return type of sum?
template <class T, class U> ??? sum(T, U);
At this time, the call using any form parameter will certainly fail at some time:
Sum (3, 4L); // if the second type is large, use U sum (T, U) sum (3L, 4); // if the first type is large, T sum (T, U)
The sum caller can forcibly convert a smaller typeThe type used as the result to solve this problem:
int i; short s; sum(static_cast<int>(s), i);
2, Use the type parameter in the return type
One way to specify the return type is to introduce the third template parameter, which must be explicitly specified by the Caller:
template <class T1,class T2,class T3>T1 sum(T2,T3);
There is a problem:No real parameter type can be used for InferenceT1TypeOn the contrary, the caller mustEach callSumHourFor this typeExplicitly provide real parameters.
int i; long lng; long val = sum<long>(i,lng);
This call explicitly specifies the T1 type, and the compiler infers the T2 and T3 types from the real parameters passed in the call.
[Summary]
Explicit template parametersMatching the template parameters from left to rightIf it can be inferred from the function parameters, only the explicit template parameters of the ending (rightmost) parameters can be ignored.
Write the sum function as follows:
template <class T1,class T2,class T3>T3 alternative_sum(T2,T1);
Real parameters must always be specified for all three parameters:
// Initialization of the template's real parameters cannot be identified long val = alternative_sum <long> (I, lng); // Error long val2 = alternative_sum <long, int, long> (I, lng); // OK
3, Explicitly participate in the function template pointer
Another example of using explicit template arguments is that section 16.2.1 contains a binary program, which can eliminate the ambiguity by using explicit template arguments:
template <typename T>int compare(const T &,const T &);void func(int (*)(const string &,const string &));void func(int (*)(const int &,const int &));func(compare<string>);
As before, you must pass the compare instance to the function named func in the call.View Only different versionsFuncParameter table to select and passCompareWhich instance is not possible?,Two different instances may meet the requirements of this call.. Explicit template parameters need to indicate which compute instance should be used and which func function should be called.
// P542 exercise 16.23 cout <max (3.14, 5) <endl; // Error cout <max <double> (5.56, 4) <endl; // OK
// Exercise 16.24/25 template <typename T, typename U> int compare (const T & val1, const U & val2) {if (val1 <val2) return-1; if (val2 <val1) return 1; return 0;} int main () {cout <compare (1, static_cast <int> (3.14) <endl; cout <compare (3.14, static_cast <double> (3) <endl; cout <compare <int> (1, 3.14) <endl; cout <compare <double> (1, 3.14) <endl; cout <compare <string, string> ("Hello", "word") <endl; cout <compare (string ("hello"), string ("Word") <endl ;}
// Exercise 16.26 template <typename T1, typename T2, typename T3> T1 sum (T2, T3); int main () {double dobj1, dobj2; float fobj1, fobj2; char cobj1, cobj2; sum (dobj1, dobj2); // Error sum <double, double, double> (fobj1, fobj2); // OK sum <int, int> (cobj1, cobj2); // OK sum <double, double> (fobj1, fobj2); // Error}