如果我有一个模板化函数,我不需要实例化它,因为它可以从参数中推断出来,如下所示:
template<typename T> void MyFunc(T arg);
int x;
MyFunc(x);
这适用于编译器可以猜出模板参数的任何情况吗?具体来说,我在想这个:
template<typename T>
class MyClass {
public:
MyClass(T) { }
};
int x;
MyClass<int> c1(x); // regular style
MyClass c2(x); // is this allowed?
答案 0 :(得分:4)
是和否。
编译器不推导类模板参数的类型,但允许默认值,因此如果您对此模板使用int
相当多,则可以执行以下操作:
template <typename T=int>
class MyClass {
public:
MyClass(T) {}
};
int x;
MyClass<> c2(x);
请注意,这仅适用于每个模板的一种特定类型。它不是根据您提供的参数类型选择类型,只是使用您为模板指定的默认值,如果您没有指定类型但是传递(比如)double
,则上面的模板会仍然在int
上实例化,而不是double
。
由于编译器可以/将推导出功能模板的模板参数,您还可以创建一个小模板函数并使用auto
:
template <class T>
MyClass<T> make_MyClass(T const &v) {
return MyClass<T>(v);
}
int x;
auto c2 = make_MyClass(x);
答案 1 :(得分:3)
不,它是不允许的,因为编译器只能在模板函数调用期间推断出类型。
也就是说,常见的解决方案是辅助功能。
template<typename T>
class MyClass {
public:
MyClass(T) { }
};
template<typename T>
MyClass<T> makeMyClass(T x)
{
return MyClass<T>(x);
}
答案 2 :(得分:2)
不,不允许;模板参数推导仅适用于模板函数,模板类不会从给定构造函数的参数中扣除模板参数。