我有以下代码(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。
答案 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
答案 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
。你得到懒惰的初始化作为一种好处。