在运行时没有关于转换的决定。是否将值转换为另一种类型的决定是在编译时做出的。
.5
无论如何,将是双重的。
a
将是您拥有的任何模板专业化,即类型T
- 乘法的结果类型(我们称之为
X
)将是任何operator*(double, T)
给出的。所有内置数字的双精度数,除了长双精度数,它给出长双精度数
- 由于您要返回 a
T
,X
因此乘法返回的值将转换为 aT
- 并且
T(0.5)
永远是T。
如果这些转换中的任何一个或operator*
未定义,则会出现编译时错误。类型与运行时无关(除非您有虚函数等)。
对您的评论:T(.5)
是 T 类型的表达式。值的转换在概念上将在运行时进行。但是,允许编译器对其进行优化,例如,如果 T 是 int,编译器将实例化T(.5)
withint(.5)
并可以立即将其优化为0
。
根据您的问题,我假设您可能不了解模板的性质。与其他一些语言中的通用函数不同,模板在编译时被评估和实例化。模板实例化意味着编译器为您使用模板的每种类型生成独立的函数。因此,例如,如果您将该函数与T=double
,T=int
并T=long double
在不同的地方使用,就好像您编写了三个函数:
double divby2(double a)
{
return .5 * a;
}
int divby2(int a)
{
return .5 * a;
}
long double divby2(long double a)
{
return .5 * a;
}
在第一个函数中,根本不会发生任何转换,因为一切都是双倍的。在第二个函数中,编译器知道 double 乘以 int 得到一个 double,但该 double 被转换回 int。您可能会收到关于此的警告。在第三个函数中,一个 double 和一个 long double 相乘得到一个 long double。由于返回类型也是 long double,所以一切都很好,您不会收到警告。