在学习和试验模板时,我遇到了一些我无法完全掌握的东西。
class sample
{
public:
sample(int a = 0) {}
};
template <typename T1,typename T2>
void add(T1 a) // Replace T1 with T2 resolves compilation error.
{}
int main()
{
add<sample>(3);
return 0;
}
上面的代码导致编译错误(03和c ++ 0x)。但是当我将添加的参数类型从T1更改为T2时,它就可以了。对于nm,创建的原型是add(sample,int)[T1 = sample,T2 = int]。为什么编译失败时T1作为参数类型而不是T2?
答案 0 :(得分:6)
指定模板参数有两种方式:显式或隐式。
这是明确的:
template<typename T>
void do_something(T value) {};
do_something<float>(6); // T is float
这是隐含的:
int x;
do_something(x); // since first argument is T and x is int, T is int
在你的情况下:
template <typename T1,typename T2> void add(T1 a);
add<sample>(3); // T1 is explcitly sample, T2 is unknown
案例2:
template <typename T1,typename T2> void add(T2 a);
add<sample>(3); // T1 is explcitly sample, T2 is implicitly int
答案 1 :(得分:1)
这是因为可以从sample
隐式创建int
类。因此,当您将<sample>
指定为类型参数时,int
会匹配第一个参数,类型为<sample>
,隐式,但T2
然后是未定义的,因为它不能推断为任何类型。
在第二种情况下不会发生这种情况,因为您会部分指定类型:<sample>
指定T1
的类型,然后可以推导出int
T2
,模板类型全部推导出来。即使没有使用所有类型,也没关系。