考虑这种代码的和平:
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
这意味着编译器为不同类型实例化相同的函数 我对么?任何人都可以解释原因吗?
答案 0 :(得分:5)
此类http(s)?://.*/dagje-uit/.*/contact/vpv/bedankt.*
将针对f
类型进行一次实例化,因为所有3个调用仅调用int
。
答案 1 :(得分:5)
来自[temp.deduct.call]:
模板参数推导是通过比较每个函数模板参数类型(称之为P)来完成的 调用的相应参数的类型(称之为A),如下所述。
P
const T&
且A
在三次调用中为int
,int
和const int
。
然后我们有:
如果P是引用类型,则P引用的类型用于类型推导。
P
是一种引用类型,因此我们使用P' == const T
来对A == int
或A == 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