Reputation: 26315
I have the following code (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;
}
I can't seem to get the initialization of s_pool
outside of the class to compile. Can anyone help me figure out how to make this work? Note I'm using C++03 only.
Upvotes: 0
Views: 111
Reputation: 299730
I think that you forgot how initializing a static data member works in general:
struct Data { int i; };
struct Holder { static Data StaticMember; };
Data Holder::StaticMember = { 1 };
^ ^~~~~~~~~~~~~~~~~~~~ static member qualified name
\~~~ static member type
If you look at your declaration, it is striking that you forgot one of the two above:
// 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
Once corrected it just works
Upvotes: 2
Reputation: 5102
EDIT: I was under the impression that:
You must explicitly give value to the static value for each instantiation of the template:
CList<int>::CMemoryPool<CList<int>::Entry>::s_pool(1);
must be somewhere in your *.C files...
Alternatively, use a static local variable in a method of the table used to get the value.
But after playing a bit, this seems to compile in ideone
template<class T>
CMemoryPool<typename CList<T>::Entry> CList<T>::s_pool(1);
I still recommend @FredOverflow solution as it protects your from static initialization problems
Upvotes: 1
Reputation: 263078
Static data members inside class templates are somewhat of a pain to initialize. I suggest a factory function instead. Then you don't need to worry about defining the variable somewhere else.
Just rewrite the line
static CMemoryPool<Entry> s_pool;
to
static CMemoryPool<Entry>& s_pool()
{
static CMemoryPool<Entry> foobar;
return foobar;
}
And then use s_pool()
instead s_pool
everywhere. You get lazy initialization as a benefit.
Upvotes: 1