让我以一个例子来说明我的问题:
template <typename T> class a{
public:
T data;
a():data(T()){}
a(T temp): data(temp) {}
};
所以如果写入main()
喜欢
a(30);
a("String");
因此,根据模板参数推导规则,它应该能够生成第一个临时类a<int>(30)
等
但我的错误是:
在'('token
>之前缺少模板参数
为什么会发生这种情况,这只适用于功能模板?
答案 0 :(得分:3)
从参数中删除模板参数仅适用于函数,永远不适用于类。在您知道类的类型(即其所有模板参数)之前,您甚至不知道该类具有哪些成员函数!
因此,如果要直接构造对象,则必须说出模板参数:
a<int> x(30);
这是一个小小的思想实验,以扩展上述内容。假设我们有
template <typename T> class Foo;
我们正在调用Foo::somefunction(x);
,其中x
是某种类型。你想,好吧,我宣布somefunction()
是这样的:
template <typename T> class Foo
{
static void somefunction(const T & x);
};
所以T
显然与x
的类型相同。但现在想象我有一个专业化:
template <> class Foo<char>
{
static void anotherfunction(double x);
};
班级Foo<char>
甚至没有拥有函数somefunction()
,因此表达式Foo::somefunction(x)
甚至没有到达我可以看到的阶段争论!
通常的做法是创建一个构造对象的免费辅助函数:
template <typename T> a<T> make_a(const T & x) { return a<T>(x); }
由于这是一个功能模板,因此可以推导出的参数:
make_a(30); // type a<int>
make_a("hello"); // type a<char[6]>
答案 1 :(得分:1)
构造函数不是一个模板,它是一个模板类。因此,当您编写a(30)
时,无法完成类模板的模板参数推导!
如果存在构造函数模板,则编译器可以推导出模板化构造函数的模板参数。例如:
template <typename T> class A{
public:
template<typename U>
A(const U &): {} //note : it's a constructor template
};
A<char> obj(30); //U is deduced as int
在上面的示例中,只能推断U
,您仍需提供T
。因为
答案 2 :(得分:0)
您仍然需要声明一个临时文件,例如a<int>(30)
。
答案 3 :(得分:0)
不幸的是,您无法从构造函数的参数推断出类模板参数。
答案 4 :(得分:0)
模板类型扣除仅适用于模板功能。您需要为模板类实例化指定参数。您可以使用函数模板推导模板参数并返回相应的类型。在c ++ 0 x中,您可以使用auto来保存实例。无法在我的手机上轻松为您编写示例代码!