
Rob,
What you've called noninstantiable should be called singleton_base so that clients derive from singleton_base.
But singleton_base has no function other than to prevent a type from being instantiated. It has no semantics relating to singleton, so it seemed reasonable to decouple them. If you want to derive a class template called singleton_base<> from noninstantiable<>, for the (sole) purpose of making client code arguably a bit easier to follow, that's fine, but the noninstantiable<> / instantiable<> class template pair stand on their own in the absence of singleton. Anyway, this is getting far off-topic.
The next point is whether requiring private ctor/dtor is better than using a noninstantiable scheme (not necessarily the one shown above).
The main point I feel is being missed is that private ctor/dtor *is* a perfectly good "noninstantiable scheme." The only difference is that it's provided by the language, and requires no code trickery on our part.
The OP's goal is to prevent instantiation of a type as both a Singleton and otherwise. [snip] The question is whether the goal is acceptable. [snip] I contend that you can provide a mechanism whereby clients can ensure their type can only be instantiated by the Singleton framework, but don't require that.
I think you've just struck the heart of the issue here. I think there are three approaches: purposely allow the flexibility you're describing, purposely disallow it, or declare it "not my problem." If you're purposely allowing classes intended for use as singletons to be instantiated elsewhere anyway, you're no longer referring to the Singleton Pattern proper anymore. That's why I thought the "noninstantiable" exercise was an interesting one: it purposely disallows instantiation in any other context, thus making the client class a singleton in the strictest sense. But back to my point: I think the philosophical difference between our two ideas is that you are purposely allowing client classes to be instantiable outside of the singleton context by explicitly stating that "derivation from singleton_base is optional," whereas I'm saying "it's not my problem: if you want a true singleton, you'll do the right thing and prevent your class from being instantiated however you please." To summarize: I feel the singleton framework should either strictly prevent all clients from being instantiated improperly, or shouldn't care at all. The third path, which I view as "optional strictness," is oxymoronic, and a waste of time for the singleton framework to attempt to provide. Regards, dr