Based on your own "dirty trick", this works in all tested compilers and does not require any code in the constructor of the derived class:
#include <iostream> template <class T> class Singleton { protected: Singleton() { instptr_ = &instance_; } static T instance_; private: static T* instptr_; }; template<class T> T Singleton<T>::instance_; template<class T> T* Singleton<T>::instptr_; class ConcreteA : public Singleton<ConcreteA> { public: ConcreteA() { std::cout << "ConcreteA constructed.\n"; } void foo(); }; int main() { //Prints 'ConcreteA constructed.'. return 0; }
My understanding of this is that using the address instance_ odr - uses it, forcing it to exist. I have to say that I am not 100% sure that this is guaranteed not to be optimized in future versions of some compiler (I tested it with -O2 everywhere).
EDIT: It seems like even writing a base class constructor like this
Singleton() { (void)&instance_; }
enough to instptr_ rid of instptr_ .
source share