2017-02-09 25 views
3

标题很拗口,但基本上我写的是这样的:我如何在声明之外为非专业化的非模板类定义方法?

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 
} 

,当我尝试编译它,我得到:

error: template-id 'A<>' for 'A<(EnumType)0u>::A(double)' does not match any template declaration

我这样做不对吗?

类似案件在网上搜索后,我试图删除template<>(即使我不明白为什么这会工作),但后来我得到

multiple definition of 'A<(EnumType)0u>::A(double)'

我想,我可以代替inlinetemplate<> (我试过并编译过),但是这并不觉得它是正确的(或者如果是这样,我不明白为什么)。

有人可以向我解释我写的是什么问题,为什么改变这似乎工作,以及有什么正确的方法来做到这一点?

回答

6

Can someone explain to me what is wrong with what I wrote, why changing this seems to work, and what's the proper way to do it ?

的标准说:

Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax.

因此,你的情况,你必须使用:

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<>是因为你没有定义已经专门的模板类的成员函数的特化构造函数的定义之前需要。

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() {} 

,并需要对函数模板的显式特(其中,我想,这就是为什么你这样在这里使用的原因)一个空的模板参数列表,非正式的,因为它告诉编译器这不是一个函数重载。

+0

我想从第二个代码片段中创建一个类的实例吗?此外,问题不在于它不是会员模板功能。 – skypjack

+1

感谢您注意到丢失的分号(但这只是我在帖子中输入的一个错字,而不是我实际的代码中的东西) – Eternal

相关问题