模板类中的静态const类型

时间:2012-01-08 19:58:17

标签: c++ templates static-variables

我一直在研究这个问题,但还没有找到解决方案。基本上我需要在模板类中初始化一个静态const类型变量。

class MyType
{
public:
    MyType (int a, int b) { }
};

template <class T>
class MyClass
{
public:
    static const MyType Type;
};

在cpp内初始化Type会产生链接器错误。在标头内初始化类型将导致它多次初始化。由于它是非整数类型,因此无法在类中初始化类型。如何在不限制类专业化的情况下解决此问题。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:3)

我不确定你的意思是“在cpp中初始化Type会产生链接器错误。”但假设你实际上意味着定义然后你必须做错了,因为在适当的位置定义每个类型的静态成员肯定有效!您在类模板中拥有的是对象的声明,如果它曾被引用,则需要在某处定义。只有当MyType碰巧是一个整数类型时,你才在类[模板]中初始化它,并且你永远不需要它的地址(例如将它绑定到一个常量引用或取其地址)你没有定义它。这是因为在这种情况下它总是被视为常量表达式。

我的猜测是你试图在某个cpp文件中定义你的对象:

template <typename T> MyType const MyClass<T>::Type = some-initialization-here;

除非您在同一翻译单元中明确或隐式地实例化此定义,否则这将无效。您可以为特定类型定义成员,如下所示:

template <> MyType const MyClass<T>::Type = some-initialization-here;

除非你真的需要这个类型是一个常量表达式,在这种情况下你通常可以侧面解决问题,如果有必要的话,可以使它成为enum(这是我倾向于做的,因为这个人可以是绑定到const引用而不需要定义),您可以使用静态成员函数,该函数可以在头文件中定义:

template <typename T>
MyType const& MyClass<T>::Type() {
    static MyType rc = some-initialization-here;
    return rc;
}
顺便说一句,我很确定这个问题之前得到了解答,绝对是comp.lang.c++.moderated

答案 1 :(得分:1)

  

在标题内初始化类型将导致多次初始化。

嗯,当然。对于MyClass实例化的每种不同类型的一次。它也是每种类型的不同对象,这是模板工作的固有特性。如果您只想定义和初始化一次,请将其放在非模板库中:

namespace detail{
class MyClassBase{
protected:
  ~MyClassBase(){} // only usable as a base class, non-polymorphic
  static const MyType Type; // only available to derived types
};
} // detail::

template<class T>
class MyClass
  : private detail::MyClassBase // private, non-polymorphic
{
public:
  using MyClassBase::Type; // if you want to expose 'Type' to the public audience
};

现在你可以放

const MyType detail::MyClassBase::Type = /*initialize here*/;

在.cpp中完成。


请注意,将static对象封装在函数中通常会更好,正如@Dietmar所示。这些函数局部静态优于任何其他类型的静态对象,因为在使用它们时不会遇到静态初始化顺序fiasco。