这是模板的正确行为吗?

时间:2014-11-03 07:46:41

标签: c++ templates

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是正确的,并且可能会给出一些背景知识吗?

1 个答案:

答案 0 :(得分:10)

是的,这是正确的行为

案例1 - 类型扣除

func<int>(d);

这使用template type deduction来确定bleh的类型。

  

为了实例化一个函数模板,必须知道每个模板参数,但不是必须指定每个模板参数。 如果可能,编译器将从函数参数推断出缺少的模板参数。当尝试进行函数调用以及执行函数模板的地址时会发生这种情况。

编译器将d的类型视为double,因此推断bleh的实际类型也必须是double

来自cppreference,也包含在C ++规范的第14.8.2节中;

  

模板参数推导尝试确定模板参数...,可以替换为每个参数P以生成推导类型A ,这与参数的类型A,...。

     

如果有多个参数,则会分别推导出每个P / A对,然后合并推导出的模板参数。如果演绎失败或对任何P / A对不明确,或者如果不同的对产生不同的推导模板参数,或者任何模板参数既未推断也未明确指定,则编译失败。

<案例2
func<int,double>(d);

bleh的类型显式设置为double,因此编译器会这样做。提供了参数d,因为它也是double,编译器很乐意继续。如果提供的参数(即代替d)的类型不是double,或者无法隐式转换为double(例如通过促销,非显式构造函数或用户提供的转换),这将导致错误。