I would like to have a templated class with a static data member, and initialize it by emulating a "static constructor." For a non-templated class, this has already been answered (see static constructors in C++? I need to initialize private static objects and What is a static constructor?). However, none of the answers seem to work for a templated class.
The following is an example that tries to adapt the "static constructor" idiom from the previous answers to a templated class. (Note that the example is simply initializing an int and could be written without such constructors; however, I require a general solution.)
#include <iostream>
struct Foo
{
static int x;
static struct init
{
init()
{
std::cout << "Initializing Foo..." << std::endl;
x = 1;
}
} initializer;
};
int Foo::x;
Foo::init Foo::initializer;
template<int N>
struct Bar
{
static int x;
static struct init
{
init()
{
std::cout << "Initializing Bar..." << std::endl;
x = N;
}
} initializer;
};
template<int N>
int Bar<N>::x;
template<int N>
typename Bar<N>::init Bar<N>::initializer;
int main()
{
std::cout << Foo::x << std::endl;
std::cout << Bar<1>::x << std::endl;
return 0;
}
This outputs:
Initializing Foo...
1
0
But I expected it to output:
Initializing Foo...
Initializing Bar...
1
1
Is this an example of the "static initialization order fiasco?"
No, it is not static initialization order fiasco. It is simply a result of the fact that every member of a template class is a template on it's own, and as such is not instantiated until used.
Your code never uses init member, so init is never instantiated.
However, your problem is easily solved:
#include <iostream>
template<int N>
struct Bar
{
static int x;
};
template<int N>
int Bar<N>::x= N;
int main()
{
std::cout << Bar<1>::x << std::endl;
return 0;
}
This gives you what you want in a simpler way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With