template<class blah, class bleh>
blah func(bleh p)
{
// Do something
}
int main()
{
double d=1.111;
int i = func<int>(d); // #1
int j = func<int,double>(d); // #2
// ....
}
在此示例中,func
,#1和#2的实例都在编译,但我不确定哪些是正确的,以及为什么。
有人可以解释为什么#1是正确的,并且可能会给出一些背景知识吗?
答案 0 :(得分:10)
是的,这是正确的行为。
func<int>(d);
这使用template type deduction来确定bleh
的类型。
为了实例化一个函数模板,必须知道每个模板参数,但不是必须指定每个模板参数。 如果可能,编译器将从函数参数推断出缺少的模板参数。当尝试进行函数调用以及执行函数模板的地址时会发生这种情况。
编译器将d
的类型视为double
,因此推断bleh
的实际类型也必须是double
。
来自cppreference,也包含在C ++规范的第14.8.2节中;
<案例2模板参数推导尝试确定模板参数...,可以替换为每个参数
P
以生成推导类型A
,这与参数的类型A
,...。如果有多个参数,则会分别推导出每个
P
/A
对,然后合并推导出的模板参数。如果演绎失败或对任何P
/A
对不明确,或者如果不同的对产生不同的推导模板参数,或者任何模板参数既未推断也未明确指定,则编译失败。
func<int,double>(d);
bleh
的类型显式设置为double
,因此编译器会这样做。提供了参数d
,因为它也是double
,编译器很乐意继续。如果提供的参数(即代替d
)的类型不是double
,或者无法隐式转换为double
(例如通过促销,非显式构造函数或用户提供的转换),这将导致错误。