2012-01-08 60 views
3

我一直在对这个问题进行一些研究,但还没有能够提出解决方案。基本上我需要在模板类中初始化一个静态常量类型变量。模板类中的静态常量类型

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

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

在cpp中初始化类型将产生链接器错误。在头文件中初始化Type会使它多次初始化。由于它是一个非整数类型,因此无法完成类内的初始化。我怎样才能解决这个问题,而不限制类专业化。任何帮助表示赞赏。

+0

“在标题内部初始化类型将导致它被多次初始化。”你能否举一个例子来说明你如何去做?如果您只是检查构造函数是否被多次调用,则应该多次调用该构造函数,因为每个模板类实例化都有一个成员。 – hvd 2012-01-08 20:02:34

回答

3

我不确定你的意思是“初始化cpp内部的类型会产生链接器错误。”但假设你实际上的意思是定义为那么你必须做错了什么,因为在适当的位置为每种类型定义静态成员当然可行!你所拥有的类模板是一个对象的声明,如果它曾经被引用过,这需要在某个地方定义。只有MyType碰巧是一个整数类型,你可以在你的类[template]中初始化它,并且你永远不需要它的地址(例如绑定到一个常量引用或者它的地址),而不用定义它。这是因为在这种情况下它始终被视为一个常量表达式。

我的猜测是,你试图定义一些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; 
} 

BTW,我嗯非常确定这个问题之前回答,绝对在comp.lang.c++.moderated

+0

请注意,该函数仍然会导致'MyClass'包含多个'MyType'对象。除此之外,+1。功能本地静力学优于类本地或全局静力学,仅仅因为你没有静态的初始化顺序而失败。 – Xeo 2012-01-08 21:01:49

+0

@Xeo:好的,确定:每个实例化一个对象。如果你不想要这个,你需要将静态成员放入一个普通的[非模板化]基类中。 – 2012-01-08 21:37:30

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所示。这些函数本地静态优于任何其他类型的静态对象,因为在使用它们时不会遇到静态初始化顺序失败。