I want to use a static member in a template class to instantiate a singleton object for each class that inherits from that template class.
Here is an example:
#include <iostream>
#include <vector>
struct X{
static std::vector<X*>& getRegistry(){
static std::vector<X*> registry;
return registry;
}
X(){
getRegistry().push_back(this); // Each X adds itself to the registry
}
};
template<typename T>
struct Y : X{
private:
static T instance; // The per-type singleton
};
template<typename T>
T Y<T>::instance {};
The idea is that objects of type X
enter themselves into a "registry" whenever they are created. Class Y<T>
that is derived from X
is a template class that should instantiate a static singleton object of each type that inherits from it (using the curiously recurring template pattern).
The idea is that the "registry" will contain one object of each class that inherits from Y<T>
. These classes should not have to do anything to get added to the registry; instead, simply inheriting from Y<T>
should be enough to create a singleton object that is added to the registry.
I tried my code like this:
struct A : Y<A>{};
struct B : Y<B>{};
struct C : Y<C>{};
int main(){
std::cout << "Number of objects in the registry: " << X::getRegistry().size() << std::endl;
// Should print "3"
}
Fiddle link: http://ideone.com/aWDEg4
The desired behaviour should be that one A
, one B
, and one C
, should be in the registry. But none of them is. The problem is that Y<T>::instance
is not instantiated for any of the classes as it is not used in the code. However, I never want to use these fields, they are just their to instantiate the singleton. So is there a way to force the instantiation of the static field without having to add additional code to the deriving classes (i.e., A
,B
, and C
)?
I know I can explicitly instantiate template class Y<A>;
, but this would add additional code to the deriving class A
.
You could just create static instances:
output: