如何为非类型模板类的特化定义声明之外的方法?

Ete*_*nal 3 c++ templates c++11

标题是满口的,但基本上我写了这样的东西:

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
}
Run Code Online (Sandbox Code Playgroud)

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

错误:'A <(EnumType)0u> :: A(double)'的template-id'A <>'与任何模板声明都不匹配

我做错了吗?

在网上搜索类似的情况后,我试图删除template<>(即使我不明白为什么这会起作用),但后来我得到了

'A <(EnumType)0u> :: A(double)'的多重定义

我想,我可以代替template<>通过inline(我试着和它编译),但是,这并不觉得自己是正确的方式做到这一点(或者,如果是这样,我不明白为什么).

有人可以向我解释我写的内容有什么问题,为什么改变它似乎有效,以及正确的方法是什么?

sky*_*ack 6

有人可以向我解释我写的内容有什么问题,为什么改变它似乎有效,以及正确的方法是什么?

标准说:

显式专用类模板的成员以与普通类成员相同的方式定义,而不使用模板<>语法.

因此,在您的情况下,您必须使用:

A<EnumType::ValA>::A(double param)
{
    // Do Stuff
}
Run Code Online (Sandbox Code Playgroud)

完全没有问题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.};
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,template<>在构造函数的定义之前是必需的,因为您没有定义已经专门化的类模板的成员函数的特化.