For static member initialization I use a nested helper struct, which works fine for non templated classes. However, if the enclosing class is parameterized by a template, the nested initialization class is not instantiated, if the helper object is not accessed in the main code. For illustration, a simplified example (In my case, I need to initialize a vector).
#include <string>
#include <iostream>
struct A
{
struct InitHelper
{
InitHelper()
{
A::mA = "Hello, I'm A.";
}
};
static std::string mA;
static InitHelper mInit;
static const std::string& getA(){ return mA; }
};
std::string A::mA;
A::InitHelper A::mInit;
template<class T>
struct B
{
struct InitHelper
{
InitHelper()
{
B<T>::mB = "Hello, I'm B."; // [3]
}
};
static std::string mB;
static InitHelper mInit;
static const std::string& getB() { return mB; }
static InitHelper& getHelper(){ return mInit; }
};
template<class T>
std::string B<T>::mB; //[4]
template<class T>
typename B<T>::InitHelper B<T>::mInit;
int main(int argc, char* argv[])
{
std::cout << "A = " << A::getA() << std::endl;
// std::cout << "B = " << B<int>::getB() << std::endl; // [1]
// B<int>::getHelper(); // [2]
}
With g++ 4.4.1:
[1] and [2] commented:
A = Hello, I'm A.
Works as intended
[1] uncommented:
A = Hello, I'm A. B =
I would expect, that the InitHelper initializes mB
- [1] and [2] uncommented:
A = Hello, I'm A. B = Hello, I'm B.
Works as intended - [1] commented, [2] uncommented:
Segfault in the static initialization stage at [3]
Thus my question: Is this a compiler bug or is the bug sitting between the monitor and the chair? And if the latter is the case: Is there an elegant solution (i.e. without explicitly calling a static initialization method)?
Update I:
This seems to be a desired behavior (as defined in the ISO/IEC C++ 2003 standard, 14.7.1):
Unless a member of a class template or a member template has been explicitly instantiated or explicitly specialized, the specialization of the member is implicitly instantiated when the specialization is referenced in a context that requires the member definition to exist; in particular, the initialization (and any associated side-effects) of a static data member does not occur unless the static data member is itself used in a way that requires the definition of the static data member to exist.