标题是满口的,但基本上我写了这样的东西:
enum EnumType{ValA, ValB};
template<EnumType> class A {};
template<>
class A<ValA>
{
private:
double param;
public:
A(double param);
};
template<>
A<ValA>::A(double param)
{
// Do Stuff
}
当我尝试编译它时,我得到:
错误:template-id&#39; A&lt;&gt;&#39; for&#39; A&lt;(EnumType)0u&gt; :: A(double)&#39;才不是 匹配任何模板声明
我这样做错了吗?
在网上搜索类似的案例后,我尝试删除template<>
(即使我不明白为什么会这样做),但后来我
&#39; A&lt;(EnumType)0u&gt; :: A(double)&#39;
的多重定义
我想我可以将template<>
替换为inline
(我试过并编译),但这并不是正确的方法(或者如果它是,我不明白为什么。)
有人可以向我解释我写的内容有什么问题,为什么改变它似乎有效,以及正确的做法是什么?
答案 0 :(得分:6)
有人可以向我解释我写的内容有什么问题,为什么改变它似乎有用,有什么方法可以做到这一点?
标准说:
显式专用类模板的成员以与普通类成员相同的方式定义,而不是使用模板&lt;&gt;语法。
因此,在您的情况下,您必须使用:
A<EnumType::ValA>::A(double param)
{
// Do Stuff
}
根本没有template<>
就好了。那是因为你实际上是专门化一个显式专用类模板的(特殊)成员函数(构造函数)
请在coliru上查看。
如果没有给出明确的专业化,那将会有所不同 作为一个最小的工作示例:
enum EnumType{ValA, ValB};
template<EnumType> class A
{
private:
double param;
public:
A(double param);
};
template<>
A<EnumType::ValA>::A(double)
{
// Do Stuff
}
int main() {
A<EnumType::ValA> a{0.};
}
在这种情况下,在构造函数的定义之前需要template<>
,因为您没有定义已经专门化的类模板的成员函数的特化。
答案 1 :(得分:0)
您在类定义结束时错过了分号(;)。 非模板成员函数可以这样定义:
A<ValA>::A(double param) {
// Do Stuff
}
非正式地,模板参数列表仅在必要时写入,例如,为了定义类模板的成员函数模板,两个模板参数列表都应该写入
template<class U, class V>
class A{
template <class T>
A();
};
template<class U, class V>
template <class T>
A<U, V>::A() {}
并且函数模板的显式特化需要一个空的模板参数列表(我猜,这就是你在这里使用的原因),非正式地,因为它告诉编译器这不是函数重载。