如何在模板类中初始化此静态类变量?

时间:2014-03-28 13:30:25

标签: c++ c++03

我有以下代码(it's on ideone.com):

template<class T>
class CMemoryPool
{
public:
    CMemoryPool(int param1)
        : stuff(param1)
    {}

private:
    T stuff;
};

template<class T>
class CList
{
public:
    struct Entry
    {
        T data;
    };

    static CMemoryPool<Entry> s_pool;
};

template<class T>
CList<T>::CMemoryPool<CList<T>::Entry>::s_pool(1);

int main()
{
    CList<int> list;
}

我似乎无法在类之外初始化s_pool进行编译。任何人都可以帮我弄清楚如何使这项工作?注意我只使用C ++ 03。

3 个答案:

答案 0 :(得分:2)

我认为您忘记了初始化静态数据成员的工作原理:

struct Data { int i; };

struct Holder { static Data StaticMember; };

Data Holder::StaticMember = { 1 };
^    ^~~~~~~~~~~~~~~~~~~~ static member qualified name
\~~~ static member type

如果你看一下你的宣言,你就会忘记上面两个中的一个:

// Only a single element: there should be a type and a name
template<class T>
CList<T>::template CMemoryPool<typename CList<T>::Entry>::s_pool(1);

// Two elements
template<class T>
CMemoryPool<typename CList<T>::Entry> CList<T>::s_pool(1);
^                                     ^~~~~~~~~~~~~~~~ name
 \~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ type

更正后it just works

答案 1 :(得分:1)

编辑: 我的印象是:

  

您必须为模板的每个实例化显式赋值静态值:

CList<int>::CMemoryPool<CList<int>::Entry>::s_pool(1);
     

必须位于* .C文件的某个位置......

     

或者,在用于获取值的表的方法中使用静态局部变量。

但是在玩了一下后,这似乎是在ideone中编译的

template<class T>
CMemoryPool<typename CList<T>::Entry> CList<T>::s_pool(1);

我仍然建议使用@FredOverflow解决方案,因为它可以保护您免受static initialization problems

的攻击

答案 2 :(得分:1)

类模板中的静态数据成员初始化有点痛苦。我建议使用工厂功能。然后你不必担心在其他地方定义变量。

只需重写一行

static CMemoryPool<Entry> s_pool;

static CMemoryPool<Entry>& s_pool()
{
    static CMemoryPool<Entry> foobar;
    return foobar;
}

然后在任何地方使用s_pool()代替s_pool。你得到懒惰的初始化作为一种​​好处。