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

时间:2015-07-08 12:16:22

标签: 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);
}

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

1
2
3

这意味着编译器为不同类型实例化相同的函数 我对么?任何人都可以解释原因吗?

3 个答案:

答案 0 :(得分:5)

此类http(s)?://.*/dagje-uit/.*/contact/vpv/bedankt.*将针对f类型进行一次实例化,因为所有3个调用仅调用int

答案 1 :(得分:5)

来自[temp.deduct.call]:

  

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

P const T&A在三次调用中为intintconst int

然后我们有:

  

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

P是一种引用类型,因此我们使用P' == const T来对A == intA == const int进行扣除。在这两种情况下,我们都会推导T == int,以便P' == const int(和P == const int&)和推导的A == const int。这比前两个调用的原始A更符合 cv - 但是明确地确定了:

  

通常,演绎过程会尝试查找将导出推导出的A的模板参数值   与A相同(在如上所述转换类型A之后)。但是,有三种情况允许   区别:
   - 如果原始P是参考类型,则推导出的A(即,参考所指的类型)可以是   比变形的A更有资格证明。

因此,所有三种情况都只需拨打f<int>

答案 2 :(得分:0)

只要类型扣除有效,它就是正确的。

考虑一下:

#include <iostream>

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

template<class T>
void f(T&& t)
{
    static int y = 0;
    std::cout<< "y=" << ++y<<std::endl;
}

template<class T>
void f(T& t)
{
    static int z = 0;
    std::cout<< "z=" << ++z<<std::endl;
}

int main()
{
    int j = 0;
    const int i = 0;
    f(5);
    f(i);
    f(j);
}

输出:

y=1
x=1
z=1