
All that said, there's still a flaw in your approach, which I've inherited in mine. That is: neither of our singleton<> class templates actually force clients to derive from their intended bases (singleton_base in your case, and noninstantiable in mine).
Okay, I figured out a way to make this work. It's terrible and I hate it, and I think the simple approach (private ctor/dtor) is best, but I feel like I have to post my solution for geeky completeness. Anyway, here it is: template <typename T> class noninstantiable { protected: virtual void myob () = 0; }; template <typename T> void noninstantiable<T>::myob () { } template <typename T> class instantiable : public T { private: virtual void myob () { this->noninstantiable<T>::myob(); } }; If this isn't self-explanatory, what's going on here is that noninstantiable<> is basically the same as before, but instantiable<> forces its clients to derive from noninstantiable by referring to its myob() member directly. So there are four scenarios: class A { }; class B : public noninstantiable<B> { }; typedef instantiable<A> C; typedef instantiable<B> D; A a; // fine B b; // error: myob not implemented C c; // error: doesn't derive from noninstantiable D d; // fine This still doesn't allow clients to write literally zero code, but it does close the loophole of case C above. Again, though, you'll have a hard time convincing me that this is even marginally better than just having a private ctor/dtor and explicitly declaring the friends who you want to allow instantiation privileges to. This approach is less safe, has more overhead, and is arcane. dr