使用模板:
template <class T>
T GetMax (T a, T b) {
return (a>b?a:b);
}
然后
int main () {
int i=5, j=6, k;
long l=10, m=5, n;
k=GetMax(i,j); // line 1
n=GetMax<int>(l,m); // line 2
n=GetMax<double>(l,m); // line 3
cout << k << endl;
cout << n << endl;
return 0;
}
我的问题是:
为什么我需要这样做:
n=GetMax<int>(l,m); // line2
如果我能做到
n=GetMax(l,m); // line 2
为什么这会编译?
n=GetMax<double>(l,m);
当 l 和 m 是一个远离双重的整数时?
答案 0 :(得分:3)
在这种情况下,您可以认为模板即时化是一个简单的文本替换(距离它不远),即一旦您找到了模板参数。所以:
T
被认为是int
。您可以在标准中找到排序匹配模板参数的确切逻辑。你的情况非常简单。 在确定模板参数之后,进行替换,因此您的函数如下所示:
int GetMax (int a, int b) {
return (a>b?a:b);
}
当您使用多个参数并且具有许多可能的继承匹配等时,它确实会被编译。
对于你的情况,你可以通过使用两种不同类型的参数来激发相等的匹配,即:GetMax(i,l)
。 T
有两个候选人:double
为int
,两者都同样出色。
这与着名的SFINAE有关(替换失败不是错误)。编译器尝试为可能的参数组合生成版本,如果失败,则不考虑最终排名。在你的情况下,两次换人成功。
您明确声明T为int
。因此编译器不会调用自动参数匹配。实例化版本看起来与1相同。
您在double
中明确说明了T.同样,编译器不会调用有关类型的任何逻辑。
盲目地为double
生成版本,并使用它:
double GetMax (double a, double b) {
return (a>b?a:b);
}
使用int
将double
传递给函数是合法的,会发生隐式转换。
这是完全合法的:
void f(double d) {};
int main(){
int i = 5;
f(i);
}
底线:
确定模板类型是一个不同于调用函数的逻辑。将其视为单独的阶段。类型推导被设计为对调用有意义,但它是一个单独的东西。
答案 1 :(得分:0)
您可以省略模板函数的类型,因为它们是在编译时扣除的
第二个问题,没有错误,因为整数回退优雅地加倍,所以它们将被转换并在模板逻辑上用作double。