在专门化模板化静态const成员时避免使用多重定义的符号

时间:2014-02-28 06:53:46

标签: c++ templates template-specialization

我遇到的问题与此处讨论的主题非常相似: How to properly specialize a templatized static const member that is the same type as its parent

这是我的代码:

template <class T>
class p3d
{
public:
    p3d() {
        x = 0;
    }

    p3d(const T &_x) {
        x = _x;
    }

    static const p3d<T> origin;

    T x;
};

typedef p3d<float> p3df;

int main(int, char**)
{
    p3df p = p3df::origin;
    return 0;
}

// elsewhere in a *.cpp file
template<> const p3df p3df::origin(0.0f);

在像Clang这样的严格编译器下编译时,我收到以下错误:

explicit specialization of 'origin' after instantiation
template<> const p3df p3df::origin(0.0f); -> implicit instantiation first required here

解决方案是移动

template<> const p3df p3df::origin(0.0f);

在typedef之前。此解决方案的问题在于它导致多重定义的符号,因为现在p3df::origin在使用向量头的每个文件中定义。有没有办法正确地专门化静态const typedef-ed模板,同时使用typedef避免所有源文件中的重复定义?

1 个答案:

答案 0 :(得分:1)

移动线

template<> const p3df p3df::origin(0.0f);

main()函数之前,但在typedef之后。

我真的不确定这里的问题是什么。似乎clang抱怨你在之后使用所述专业化提供模板专业化的定义。 gcc / 4.9(每晚构建)没有问题。

一般来说,在头文件中使用静态模板定义很酷,因为它们 - 顾名思义 - 模板。但是,如果您专门化模板,从而使其成为实际类,则一个定义规则适用于任何常规类,您需要将定义移动到非头文件。