模板演绎有趣的案例,c ++

Edu*_*yan 4 c++ templates instantiation type-deduction

考虑一下代码的和平:

template<class T>
void f(const T& t)
{
    static int x = 0;
    cout<<++x<<endl;
}

int main()
{
    int j = 0;
    const int i = 0;
    f(5);
    f(i);
    f(j);
}
Run Code Online (Sandbox Code Playgroud)

我已经调用了3种类型的函数.虽然5和j可以是同一个东西,但只是int,const int i绝对是不同的类型.
但无论如何我的输出是:

1
2
3
Run Code Online (Sandbox Code Playgroud)

这意味着编译器为不同类型实例化相同的函数.
我对么?谁能解释为什么?

For*_*veR 5

f对于类型int,这里将被实例化一次,因为所有3个调用都只是调用f<int>.


Bar*_*rry 5

来自[temp.deduct.call]:

模板参数推导是通过将每个函数模板参数类型(称为P)与调用的相应参数的类型(称为A)进行比较来完成的,如下所述.

Pconst T&A现在int,int以及const int在三个电话中.

然后我们有:

如果P是引用类型,则P引用的类型用于类型推导.

P是一种参考类型,所以我们P' == const T用来扣除A == intA == const int.在这两种情况下,我们推断T == int,这样P' == const int(和P == const int&)和推导A == const int.对于前两个调用,这比原来的更加cv- qualified A,但是明确地确定了:

通常,推导过程试图找到模板参数值,这将使推导出的A与A相同(在如上所述转换类型A之后).但是,有三种情况允许存在差异:
- 如果原始P是引用类型,则推导出的A(即引用所指的类型)可以比转换后的A更具有cv限定.

因此,所有三种情况都只是打电话f<int>.