
The documentation for the singleton is finished. I didn't end up writing a tutorial for extending the library after all, because it turned out that I already described the policy interfaces clearly in my reference section and didn't have much to add to them. Instead, I made sure that the tutorial had lots of links to the most important reference pages. New in this release is the addition of the cleanup class and the zombie singleton walk through. In addition, I did a bunch of minor bug fixing, most of which I don't remember, and most of which wouldn't affect most client code. I think one of the things I fixed was making sure that the malloc_creator frees the memory if construction throws. Anyhow, the new package is in the sandbox, enjoy! -Jason

I can't get the singleton to work with VC70. The error message is \boost\singleton\creators.hpp(171): error C2504: 'boost::singleton::detail::longevity_registry<Unused>' : base class undefined with [ Unused=void ] My code looks like: struct manipidx { manipidx() : idx(std::ios_base::xalloc()) { } int idx; }; typedef basic_singleton<manipidx> tmanipidx; int main() { std::cout << tmanipidx::pointer()->idx << std::endl; } What I'm trying to do is to create a global variable that can be used in all instanses of a template and at the same time avoid the need for a .cpp file.

Martin wrote:
I can't get the singleton to work with VC70.
The error message is
\boost\singleton\creators.hpp(171): error C2504: 'boost::singleton::detail::longevity_registry<Unused>' : base class undefined with [ Unused=void ]
My code looks like:
struct manipidx { manipidx() : idx(std::ios_base::xalloc()) { } int idx; };
typedef basic_singleton<manipidx> tmanipidx; int main() { std::cout << tmanipidx::pointer()->idx << std::endl; }
What I'm trying to do is to create a global variable that can be used in all instanses of a template and at the same time avoid the need for a .cpp file.
That's really strange, what you are trying to do should work. I think there are computer labs at school which have VC70, I'll test your code out there later today and see if I can't get it fixed. In the mean time, have you tried using the singleton as a base class rather than a typedef? struct manipidx : boost::basic_singleton <manipidx> { manipidx() : idx(std::ios_base::xalloc()) { } int idx; }; int main() { std::cout << manipidx::pointer()->idx << std::endl; } -Jason

The singleton library does not work on VC70, and I am having difficulty figuring out a work-around. Below, I have written a stripped down version of the singleton hierarchy which demonstrates the problem. Can someone more familiar with VC70 think of a way to make the code compile? I suspect I need an extra level of indirection somewhere, but I'm not sure quite where to put it. Thanks in advance. template < typename Type > struct creator { struct creatable : public Type // --- ERROR HERE, SAYS TYPE IS NOT YET DEFINED --- { }; }; template < typename Type > struct lifetime { creator < Type > my_creator; struct pointer { }; }; template < typename Type > struct singleton { struct pointer : public lifetime < Type >::pointer { }; }; // client code struct client_singleton : public singleton < client_singleton > { };

Jason Hise wrote:
The singleton library does not work on VC70, and I am having difficulty figuring out a work-around. Below, I have written a stripped down version of the singleton hierarchy which demonstrates the problem. Can someone more familiar with VC70 think of a way to make the code compile? I suspect I need an extra level of indirection somewhere, but I'm not sure quite where to put it. Thanks in advance.
template < typename Type > struct creator { struct creatable : public Type // --- ERROR HERE, SAYS TYPE IS NOT YET DEFINED --- { }; };
template < typename Type > struct lifetime { creator < Type > my_creator;
struct pointer { }; };
template < typename Type > struct singleton { struct pointer : public lifetime < Type >::pointer { }; };
// client code struct client_singleton : public singleton < client_singleton > { };
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Excellent news, I think I've found a work-around. If it works, I'll follow up with a new upload. -Jason

I have personally verified that the library now works with .NET 2002, 2003, 2005, and with Dev-C++. A new package has been uploaded which in addition to the new code and updated docs contains two source files. Compiling these two files successfully should verify that the singleton will work on your compiler. If they don't compile, please let me know immediately so that I can fix them. Recent changes include: * create_statically uses a static instance instead of aligned_storage. I am starting to think that create_statically is a bad policy altogether, and am tempted to remove it. For a creation policy that always creates and destroys the instance in the same place in memory, you should write an allocator policy which always returns the same memory location and use it with create_using_std_allocator_ex. * creatable classes defined inside creators are now templated because it makes VC 7.0 happy and doesn't hurt anything. As always, the code is in the sandbox (http://boost-sandbox.sourceforge.net/vault/) -Jason

Thanks, it compiles now and works but I do get several warnings (also with the test programs), see below. Just a question. Is it possible to have the singleton automaticly created at program start? (A global variable isn't an option since that is what I'm trying to avoid in the first place) Here are the warnings (they are repeated several times) boost\singleton\leaky_lifetime.hpp(207) : warning C4512: 'boost::singleton::leaky_lifetime_ex<CreationPolicy,Creator,Lock>::lifet ime<Type>::auto_set<T>' : assignment operator could not be generated boost\singleton\creators.hpp(174) : warning C4511: 'boost::singleton::create_using_new_ex<NoThrow>::creator<Type>::creatabl e<Base>' : copy constructor could not be generated boost\singleton\creators.hpp(181) : warning C4127: conditional expression is constant boost\singleton\leaky_lifetime.hpp(77) : warning C4127: conditional expression is constant

Martin wrote:
Thanks, it compiles now and works but I do get several warnings (also with the test programs), see below.
Just a question. Is it possible to have the singleton automaticly created at program start? (A global variable isn't an option since that is what I'm trying to avoid in the first place)
Keep at least one global or static pointer to the singleton. The global pointer is different in concept than a real global instance, as it is being used to control the moment of creation, rather than to provide a global point of access. You can hide the global pointer in an unnamed namepace in some obscure source file if you want to make it really clear that it isn't the access mechanism.
Here are the warnings (they are repeated several times) boost\singleton\leaky_lifetime.hpp(207) : warning C4512: 'boost::singleton::leaky_lifetime_ex<CreationPolicy,Creator,Lock>::lifet ime<Type>::auto_set<T>' : assignment operator could not be generated
boost\singleton\creators.hpp(174) : warning C4511: 'boost::singleton::create_using_new_ex<NoThrow>::creator<Type>::creatabl e<Base>' : copy constructor could not be generated
Disabling of the singleton's default copy constructor was intentional, you can ignore or disable this warning.
boost\singleton\creators.hpp(181) : warning C4127: conditional expression is constant boost\singleton\leaky_lifetime.hpp(77) : warning C4127: conditional expression is constant
The conditional expression is a template argument (whether or not to use nothrow new), and ideally the condition itself should be optimized away by the compiler because it is constant. Perhaps I need to add some #pragma warning disablers for when the code is compiled with visual studio. The warnings you are getting should be harmless. -Jason

Keep at least one global or static pointer to the singleton. The global pointer is different in concept than a real global instance, as it is being used to control the moment of creation, rather than to provide a global point of access. You can hide the global pointer in an unnamed namepace in some obscure source file if you want to make it really clear that it isn't the access mechanism.
The problem is that I don't have a source files to put a global variable in. My library is a template that lives entierly in header files. At the moment I got a single cpp file that only contains the global variable. It works but it forces the library users to include the source file in their project so I would like to get rid of it. The singleton seem to solve the problem but since the global variable isn't created until it is used it could happen that two threads create it at the same time. The global variable is constant so it is only the creation that needs locking. I could use a locking policy but it would be easier if I could just force creation at startup.
Disabling of the singleton's default copy constructor was intentional, you can ignore or disable this warning.
Why does a singleton need a copy contructor?

Martin wrote:
Keep at least one global or static pointer to the singleton. The global pointer is different in concept than a real global instance, as it is being used to control the moment of creation, rather than to provide a global point of access. You can hide the global pointer in an unnamed namepace in some obscure source file if you want to make it really clear that it isn't the access mechanism.
The problem is that I don't have a source files to put a global variable in.
My library is a template that lives entierly in header files. At the moment I got a single cpp file that only contains the global variable. It works but it forces the library users to include the source file in their project so I would like to get rid of it.
The singleton seem to solve the problem but since the global variable isn't created until it is used it could happen that two threads create it at the same time. The global variable is constant so it is only the creation that needs locking. I could use a locking policy but it would be easier if I could just force creation at startup.
Well, I guess I don't see any problem with declaring the global pointer in the header... maybe just put it in a detail namespace. An extra pointer will exist in each translation unit, but that shouldn't cause any problems.
Disabling of the singleton's default copy constructor was intentional, you can ignore or disable this warning.
Why does a singleton need a copy contructor?
It doesn't... which is why I disabled it by declaring it privately and not defining it. If I had ignored it a default copy ctor would have been generated. The error is saying that a class deriving from the singleton was unable to generate its own automatic copy constructor because the derived class couldn't access the base's copy constructor, which I had made private and disabled. This is intentional. -Jason

I have revised the design of the singleton many times, thanks to the plethora of helpful suggestions from testers (most notably Pavel Vozenilek, thanks a ton!). The library has reached a stage where changes being made now are minor, and mostly have to do with implementation details and getting the singleton to work on legacy compilers. The draft documentation is complete, though I still plan to add more examples and sample code. The library compiles on at least four popular compilers. I believe that I am truly ready to schedule a formal review. Can singleton be added to the queue? On a related note, I have convinced the local college to give me three credit hours for the 'independent study' that I am doing (creating the singleton library). I understand that the review queue is filled for the next couple of months, but I wanted to find out if there was any chance that the singleton review could be completed before the end of the semester. Getting the library accepted into boost before classes let out would almost certainly ensure an 'A' in the class. Of course, if this is impossible I'll understand. I just thought I'd ask. :) -Jason

Does the standard specify whether static variables are destroyed before or after atexit is triggered? -Jason

Jason Hise wrote:
Does the standard specify whether static variables are destroyed before or after atexit is triggered?
I've pasted in section 3.6.3 of the standard. Jonathan ---------- 3.6.3 Termination Destructors (12.4) for initialized objects of static storage duration (declared at block scope or at namespace scope) are called as a result of returning from main and as a result of calling exit (18.3). These objects are destroyed in the reverse order of the completion of their constructor or of the completion of their dynamic initialization. If an object is initialized statically, the object is destroyed in the same order as if the object was dynamically initialized. For an object of array or class type, all subobjects of that object are destroyed before any local object with static storage duration initialized during the construction of the subobjects is destroyed. If a function contains a local object of static storage duration that has been destroyed and the function is called during the destruction of an object with static storage duration, the program has undefined behavior if the flow of control passes through the definition of the previously destroyed local object. If a function is registered with atexit (see <cstdlib>, 18.3) then following the call to exit, any objects with static storage duration initialized prior to the registration of that function shall not be destroyed until the registered function is called from the termination process and has completed. For an object with static storage duration constructed after a function is registered with atexit, then following the call to exit, the registered function is not called until the execution of the object's destructor has completed. If atexit is called during the construction of an object, the complete object to which it belongs shall be destroyed before the registered function is called. Calling the function void abort(); declared in <cstdlib> terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit().

I use the following as an implementation detail, and it was mentioned by Pavel that a similar facility called state_saver is used in the implementation of the serialization library. Does it make sense for this to be refactored into boost/detail? template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) : var ( var ), val ( val ) { } ~ auto_set ( ) { var = val; } }; -Jason

Jason Hise wrote:
I use the following as an implementation detail, and it was mentioned by Pavel that a similar facility called state_saver is used in the implementation of the serialization library. Does it make sense for this to be refactored into boost/detail?
template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) :
auto_set(T & var,T val = T()): // allows one to just specify a variable to be auto-set back to its default value also
var ( var ), val ( val ) { } ~ auto_set ( ) { var = val; } };

template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) :
auto_set(T & var,T val = T()): // allows one to just specify a variable to be auto-set back to its default value also
var ( var ), val ( val ) { }
// IMHO I thing it´s more often useful to use var own value to be restored later: auto_set(T& var) : var(var), val(var) { }
~ auto_set ( ) { var = val; } };

Sérgio Vale e Pace wrote:
template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) :
auto_set(T & var,T val = T()): // allows one to just specify a variable to be auto-set back to its default value also
var ( var ), val ( val ) { }
// IMHO I thing itŽs more often useful to use var own value to be restored later: auto_set(T& var) : var(var), val(var) { }
~ auto_set ( ) { var = val; } };
Good point ! I agree. We then need two constructors, with the one not taking a value resetting the variable back to its initial value.

Sérgio Vale e Pace wrote:
template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) :
auto_set(T & var,T val = T()): // allows one to just specify a variable to be auto-set back to its default value also
var ( var ), val ( val ) { }
// IMHO I thing it´s more often useful to use var own value to be restored later: auto_set(T& var) : var(var), val(var) { }
~ auto_set ( ) { var = val; } };
Perhaps. You might be interested to see why I originally wrote it though: virtual void create ( ) { if ( !s_inst && !creating ) { creating = true; auto_set < bool > reset ( creating, false ); s_inst = creator_inst.create ( ); } } virtual void destroy ( ) { if ( s_inst && !destroying ) { destroying = true; auto_set < bool > reset_d ( destroying, false ); auto_set < raw_pointer > reset_p ( s_inst, 0 ); creator_inst.destroy ( s_inst ); } } Basically, when create is called, the constructor of the singleton being created just might do something that would normally cause that singleton to be automatically created. I use a bool to remember that a creation is in progress, and auto_set makes sure that it gets turned off when the scope is exited. The same kind of thing is going on in destroy, but I also ensure that the pointer to the singleton gets reset to null after destruction is complete. -Jason

Perhaps. You might be interested to see why I originally wrote it though: what you are doing are very common in multithreaded code. perhaps you consider using this:
virtual void create ( ) { if ( !s_inst && !creating ) { auto_set < bool > reset (creating); creating = true; s_inst = creator_inst.create ( ); } }
the destructor goes basically the same way. But it´s not a really big difference.
-Jason Sérgio

From: Jason Hise <chaos@ezequal.com>
I use the following as an implementation detail, and it was mentioned by Pavel that a similar facility called state_saver is used in the implementation of the serialization library. Does it make sense for this to be refactored into boost/detail?
template < typename T > struct auto_set { T & var; T val; auto_set ( T & var, T val ) : var ( var ), val ( val ) { } ~ auto_set ( ) { var = val; } };
I could see calling that auto_reset, but not auto_set. You do realize that this would have to be documented as requiring that T's copy assignment operator be nonthrowing, right? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Early on, I had the idea to disable creation of a user's singleton by making the base class have one pure virtual function. The user's derived singleton would become an abstract class, and thus not be able to be instantiated. Then the user would refer to the singleton via an even further derived class, like follows: class singleton_base { private: virtual void define_to_enable_creation ( ) = 0; }; template < typename Type > class singleton : public Type { private: virtual void define_to_enable_creation ( ) { } protected: // constructors and such were here public: // interface was here }; //------------------------------------------------- class test_singleton : public singleton_base { public: void do_something ( ); }; int main ( ) { test_singleton t; // this line would not compile singleton < test_singleton > t2; // neither would this singleton < test_singleton >::pointer ptr; // this would be the only access mechanism ptr->do_something ( ); return 0; } This idea concerned some originally because remembering to use singleton < test_singleton > instead of just test_singleton everywhere in client code could get ugly, and define_to_enable_creation was the only virtual function in the class, introducing what might be unacceptable overhead. As a result, I removed it and changed the design to a more conventional CRTP implementation. I resigned myself to the fact that the user would just need to remember to make the default ctor and dtor protected. In the current incarnation of the library, the client singleton's constructors are protected, and to gain access to them the creator policies define their own private class internally which derives from the singleton type and makes the ctors and dtor public. This is similar to the pattern above, except that client code doesn't have to worry or know about that most derived rung on the class hierarchy. If I were to re-enable the virtual function check to make the client singleton abstract, the overhead of using virtual functions would again come back. However, having it in place would prevent unsafe instantiations regardless of the access level client code uses for singleton constructors. So would there be any objections to reinstating this mechanism just in debug mode? This way unsafe instantiations could be caught, and in release mode you wouldn't have to pay for the catching mechanism at all. Thoughts? -Jason

Hi Jason, I haven't looked at singleton in any detail, so I can't answer your real question, but I wanted to offer a small suggestion, for what it's worth: Rather than having a special function spelled "define_to_enable_creation," I wonder if it would be reasonable to declare singleton_base's destructor as pure virtual, forcing client code such as test_singleton to implement a destructor. If you wanted to enable the virtual behavior only for extra checking in debug mode, that'd be fine too: class singleton_base { protected: #ifdef DEBUG virtual ~singleton_base() = 0; #endif // ... }; class test_singleton : public singleton_base { protected: ~test_singleton() { } // ... }; In debug mode, test_singleton's destructor is virtual as defined by its base class, and is necessary to implement. In release mode, test_singleton's destructor is not virtual unless you specify it to be. And implementing a trivial destructor like this is never harmful anyway. Just a thought, but I might be totally missing something :) Cheers, dr On Thu, 24 Mar 2005 10:27:13 -0500, Jason Hise <chaos@ezequal.com> wrote:
Early on, I had the idea to disable creation of a user's singleton by making the base class have one pure virtual function. The user's derived singleton would become an abstract class, and thus not be able to be instantiated. Then the user would refer to the singleton via an even further derived class, like follows:
class singleton_base { private: virtual void define_to_enable_creation ( ) = 0; };
template < typename Type > class singleton : public Type { private: virtual void define_to_enable_creation ( ) { }
protected: // constructors and such were here
public: // interface was here };
//-------------------------------------------------
class test_singleton : public singleton_base { public: void do_something ( ); };
int main ( ) { test_singleton t; // this line would not compile singleton < test_singleton > t2; // neither would this singleton < test_singleton >::pointer ptr; // this would be the only access mechanism ptr->do_something ( );
return 0; }
This idea concerned some originally because remembering to use singleton < test_singleton > instead of just test_singleton everywhere in client code could get ugly, and define_to_enable_creation was the only virtual function in the class, introducing what might be unacceptable overhead. As a result, I removed it and changed the design to a more conventional CRTP implementation. I resigned myself to the fact that the user would just need to remember to make the default ctor and dtor protected.
In the current incarnation of the library, the client singleton's constructors are protected, and to gain access to them the creator policies define their own private class internally which derives from the singleton type and makes the ctors and dtor public. This is similar to the pattern above, except that client code doesn't have to worry or know about that most derived rung on the class hierarchy.
If I were to re-enable the virtual function check to make the client singleton abstract, the overhead of using virtual functions would again come back. However, having it in place would prevent unsafe instantiations regardless of the access level client code uses for singleton constructors. So would there be any objections to reinstating this mechanism just in debug mode? This way unsafe instantiations could be caught, and in release mode you wouldn't have to pay for the catching mechanism at all. Thoughts?
-Jason
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Do Boost threads compile and run on platforms without pthreads? I'm having problems on HP where the headers claim that pthreads are not completely implemented and Boost thread compilation fails. --Suman

On Thu, 24 Mar 2005 08:47:58 -0800 Dan Rosen <dan.rosen@gmail.com> wrote:
Hi Jason,
I haven't looked at singleton in any detail, so I can't answer your real question, but I wanted to offer a small suggestion, for what it's worth:
Rather than having a special function spelled "define_to_enable_creation," I wonder if it would be reasonable to declare singleton_base's destructor as pure virtual, forcing client code such as test_singleton to implement a destructor. If you wanted to enable the virtual behavior only for extra checking in debug mode, that'd be fine too:
class singleton_base { protected: #ifdef DEBUG virtual ~singleton_base() = 0; #endif // ... };
class test_singleton : public singleton_base { protected: ~test_singleton() { } // ... };
In debug mode, test_singleton's destructor is virtual as defined by its base class, and is necessary to implement. In release mode, test_singleton's destructor is not virtual unless you specify it to be. And implementing a trivial destructor like this is never harmful anyway.
Just a thought, but I might be totally missing something :) Cheers, dr
I do not understand what Jason is after either, but I thought a virtual destructor may offer some assistance, and it may, depending on what he is really trying to achieve. However, I thought I'd comment on your suggestion... A pure virtual destructor in singleton_base does not require the derived class to implement a destructor. Well, it does, but the compiler will automatically generate a destructor in the derived class. So you do not get the benefit or "forcing" the derived class to implement the destructor. Second, you still must provide an implementation of singletom_base::~singleton_base() because derived classes will call it in their destruction process. Remember pure virtual functions (including destructors) can have an implementation, and specifically for dtors, you must provide such implementation.

Right you are. I guess that's what I'm missing, among other things :P dr On Thu, 24 Mar 2005 14:14:50 -0500, Jody Hagins <jody-boost-011304@atdesk.com> wrote:
Just a thought, but I might be totally missing something
A pure virtual destructor in singleton_base does not require the derived class to implement a destructor.

Jody Hagins wrote:
On Thu, 24 Mar 2005 08:47:58 -0800 Dan Rosen <dan.rosen@gmail.com> wrote:
Hi Jason,
I haven't looked at singleton in any detail, so I can't answer your real question...
I do not understand what Jason is after either...
Alright, allow me to clarify. I want the singleton to behave as follows: class test : public singleton < test > { // no constructors or destructor provided // all of the defaults are generated }; int main ( ) { client c; // should still be illegal, and fail to compile return 0; } I do not want to force client code to define protected constructors and destructors if they would not normally need them. But the only way to disable creation without explicitly making the functions in the client class protected is to somehow make the client class pure virtual. This is achieved with a pure virtual function in the base with an obfuscated name client code is unlikely to implement on its own, and when the client fails to implement this function, the client class becomes pure virtual, and thus, is not creatable. Adding this virtual function adds overhead to the class. So I want to only provide this check in debug mode. My thinking is that all illegal uses will be caught, and then the release mode version won't have to pay the price for the safety net. My main worry is that the hole I am leaving in release mode could potentially be abused. Is disabling the check in release mode a good idea, or potentially dangerous enough that I should always leave the check enabled? Would it perhaps be better to check for a different symbol than NDEBUG, so that by default the check would always be enabled, but client code could explicitly disable the check if the overhead was a problem? Is there another way altogether that I can do this check without the overhead? As always, I am open to suggestions. -Jason

Jason Hise wrote:
class test : public singleton < test > { // no constructors or destructor provided // all of the defaults are generated };
int main ( ) { client c; // should still be illegal, and fail to compile return 0; }
small correction, where it says 'client' it should read 'test': int main ( ) { */test/* c; // should still be illegal, and fail to compile return 0; } -Jason

Jason, I think the part we're missing is the motivation behind this:
Alright, allow me to clarify. I want the singleton to behave as follows: [snip] I do not want to force client code to define protected constructors and destructors if they would not normally need them.
Why do you consider it so burdensome for client code to define protected or private ctors/dtors that this has become a primary design consideration? Of all the boilerplate code we have to write in our day-to-day experience with C++, in my opinion, ctor/dtor declarations aren't nearly the most odious. On top of that, I think that just about any class that's worth making a singleton will contain some state, and is therefore likely to need an explicitly declared ctor and/or dtor. Also, for what it's worth, you'll notice if you look at Loki's embodiment of the singleton pattern, that despite all its flexibility and all the thought that went into it, clients of its SingletonHolder class still must declare their ctor and dtor private. To put it a different way: whether the client provides a trivial implementation of a virtual function with an obfuscated name, or whether the client implements private ctor and dtor, the client still has to do *something* to enable proper usage. In the former case the client is enabling correct construction and in the latter it's disabling incorrect construction, but they're essentially equivalent in that clients are forced to do some work. So my recommendation would be: choose the route that's most idiomatic. We all know what it means when ctors/dtors are declared private in an interface, whereas implementing an arbitrarily-named and unused virtual function to achieve essentially the same result is less clear and less familiar. I hope I haven't missed some important reason why you need a singleton that operates this way... Hope this helps, dr

Dan Rosen wrote:
To put it a different way: whether the client provides a trivial implementation of a virtual function with an obfuscated name, or whether the client implements private ctor and dtor, the client still has to do *something* to enable proper usage.
But this is not what I was suggesting. The client code at no point needs to even know that the virtual function exists, and it certainly shouldn't provide an implementation for it. The virtual function is declared in the singleton base class, and defined in the creator, both of which are provided by the library. The hierarchy is: singleton < test > (provided by library, pure virtual) | test (provided by client code, pure virtual) | creatable < test > (used internally by library and hidden from client code, concrete) This makes it so that client code can indeed do absolutely nothing, and still be guaranteed that rogue instances cannot be created. -Jason

But this is not what I was suggesting. [snip] This makes it so that client code can indeed do absolutely nothing, and still be guaranteed that rogue instances cannot be created.
Ah, interesting pattern. Thanks for the clarification. I think there are two separable design concerns here. One is the singleton behavior, and the other is the non-instantiable behavior. Singleton conceptually has a dependency on non-instantiable, but there isn't a reverse dependency there. So I'd separate the two something like this: class noninstantiable { protected: virtual void myob () = 0; }; template <typename T> class instantiable : public T { private: virtual void myob () { } }; That's the first half -- it's saying something like "a class deriving from noninstantiable is not instantiable except in certain contexts where you explicitly declare it to be instantiable." [Clients are also prevented from calling myob().] This doesn't prevent clients from intentionally saying "I want to instantiate foo here" by using instantiable<foo> explicitly, but it does prevent unintentional instantiation, which is probably good enough. The second half is the singleton part. You'd do something like: template <typename T> class singleton : public instantiable<T> { // ... }; 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). In other words, your assertion that "client code can indeed do absolutely nothing" isn't precisely true: clients still have to derive from a special base to be safe, and there's no guarantee that will be done. Addressing your original question regarding whether enabling the virtual function safety mechanism in debug mode, that seems reasonable. Assuming there's nothing wrong with the way I've refactored things here, you can contain that safety mechanism within the noninstantiable/instantiable hierarchy without polluting the singleton's interface. (Just wrap the declarations for "myob" in an #ifdef DEBUG block and you're done.) But I'd still like to know your motivation for not just doing what strikes me as the obvious and idiomatic thing: making clients define private ctor/dtor. It's trivial to do, everybody knows what it means, and you get the same safety without any virtual function overhead. Is there some reason you're trying so hard to avoid this? Cheers, dr

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

DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:references; b=MZ2/STCvbocBJRKdRXXSdw8PEyGA45EQ1ZT81RfX2GtTF/tK2gXcyhr9okaGWB5dxhggJkBvr8eZCj4/GF+w/HM25bcs9e6kJI5arrFDY7nZi8UV747ffQUJBAUo/TykzCLAUq5VbtTDIuXp2khe/tV/B5NiFg7Wnz4ag9A2+FM= From: Dan Rosen <dan.rosen@gmail.com>
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.
Let me address a couple of points raised. First, assuming what you've outlined is an acceptable approach, what you've called noninstantiable should be called singleton_base so that clients derive from singleton_base. (Adjust the other names similarly.) The next point is whether requiring private ctor/dtor is better than using a noninstantiable scheme (not necessarily the one shown above). The OP's goal is to prevent instantiation of a type as both a Singleton and otherwise. If you accept that goal, then you want to prevent mistakes and a noninstantiable scheme is needed. Otherwise, it is easy to forget to Do The Right Thing (tm) and ensure your class can't be both a Singleton and not. I prefer to have the compiler catch mistakes and, if you accept the stated goal, this is a mistake that the compiler can catch. The question is whether the goal is acceptable. Consider a printer Singleton. There may be one, default printer, and that can be captured quite handily via a Singleton. The question is: Can there be other printers? Obviously, there can, so preventing instantiation of printer outside the Singleton framework is overkill. 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. IOW, singleton_base could be used to prevent non-Singleton instantiation, but make its use optional. (Making it optional also prevents MI problems for types that already derive from other classes.) Thus, I think the framework should permit singleton<A> and singleton<B> (where noninstantiable is called singleton_base). -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
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 already do :) You can use a type deriving from the singleton if you want true singleton behavior, or you can use a typedef if you want one globally managed resource and any number of local resources. class A : public singleton < A > { /*...*/ }; // only the singleton instance can exist class B { /*...*/ }; // can create any number of B instances typedef singleton < B > global_b; // but global_b manages the lifetime of one global B instance. There is a multiton for cases when you need multiple global instances that uses key based identification, and alternately you can derive a different type from B for each global instance you want managed. class Printer { /*...*/ }; class PrinterA : public Printer, public singleton < PrinterA > { }; class PrinterB : public Printer, public singleton < PrinterB > { }; -Jason

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

DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=beta; d=gmail.com; h=received:message-id:date:from:reply-to:to:subject:in-reply-to:mime-version:content-type:content-transfer-encoding:references; b=pF+Zvpraxj4DWHKMjzQDRNtCoQ+iETlCcRxdPY/967Dba6UptVfsPJa3+DVBRHCDo4Yts3/JhkPhE5bOK1ckoBgblZ1gU2pNeajuhu+GYkpZA56afZxcAAxCOIvwyaAMV2hSgs2L6NiM0DaGjSk/iqVQknAxL4WF4H+RAWiKl1Q= From: Dan Rosen <dan.rosen@gmail.com>
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
Agreed, but...
template called singleton_base<> from noninstantiable<>, for the (sole) purpose of making client code arguably a bit easier to follow,
Exactly. Rather than a Singleton library client needing to know that they are making a Singleton class noninstantiable, they only know they're declaring it to be used by the library. An advanced usage section can document that deriving from the base class is not needed, and that omitting that derivation permits separate instantiations of the class.
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.
I'm not certain this is off topic. Yes, I agree that noninstantiable/instantiable could be valuable components in their own right. Whether singleton_base is implemented in terms of noninstantiable, or is merely a duplicate of the technique isn't worrisome to me.
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.
I didn't miss that. I was simply thinking of it from the perspective of the Singleton library client: with: class make_me_a_singleton : public singleton_base { ... }; without: class make_me_a_singleton { ... private: make_me_a_singleton() { }; ~make_me_a_singleton() { }; }; To me, the first ("with") version is clearer. It doesn't force defining private ctor/dtors that aren't otherwise needed and its intent is more apparent. The first version is achievable just as easily with noninstantiable as with singleton_base. If singleton_base offers nothing more than noninstantiable, then the choice of names is debatable.
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
Good summary.
singletons to be instantiated elsewhere anyway, you're no longer referring to the Singleton Pattern proper anymore. That's why I
It isn't clear that the library is or must slavishly follow the GoF Singleton Pattern. It can support more functionality without loss of clarity, IMO.
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.
Fine.
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 make the class instantiable by the framework, the supplied Creator policy class must have access to the ctor. You can make the ctor private and then make the Creator a friend, but then outside code can call creator<T>::create() to create an instance. If creator<T>::create() is private, and singleton<T> is a friend, then only singleton<T> can instantiate a T. That, of course, is a lot of machinery just to ensure that T can only ever be instantiated as a Singleton. It would be nice if T could be its own Creator. Then, using CRTP, T could be noninstantiable and its own Creator by deriving from, say, singleton::simple_singleton: class make_me_a_singleton : public <simple_singleton<make_me_a_singleton> { ... }; My point is that just making the ctors private doesn't close the access hole.
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.
It isn't a waste if it simplifies syntax. -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
with:
class make_me_a_singleton : public singleton_base { ... };
without:
class make_me_a_singleton { ... private: make_me_a_singleton() { }; ~make_me_a_singleton() { }; };
To me, the first ("with") version is clearer. It doesn't force defining private ctor/dtors that aren't otherwise needed and its intent is more apparent.
Thank you, those are my thoughts precisely :)
The first version is achievable just as easily with noninstantiable as with singleton_base. If singleton_base offers nothing more than noninstantiable, then the choice of names is debatable.
If you check the current version of the library, you will notice that 'singleton_base' offers a lot more than non-instantiable, specifically in the realm of control over the instance lifetime, dependency management between multiple singletons, and safety with regard to using singletons that have already been destroyed.
To make the class instantiable by the framework, the supplied Creator policy class must have access to the ctor. You can make the ctor private and then make the Creator a friend, but then outside code can call creator<T>::create() to create an instance. If creator<T>::create() is private, and singleton<T> is a friend, then only singleton<T> can instantiate a T. That, of course, is a lot of machinery just to ensure that T can only ever be instantiated as a Singleton.
I agree, this might be a bit much machinery, especially because creator policies are likely to be written often by client code. However, there is a way to move all of the machinery into the library, so that client written creators don't have to re-implement it. Create and destroy are not static functions, as a creator must be allowed to have a saved state. These are just plain old member functions, and require a creator instance in order to be called. Thus, by adding a creator base with a pure virtual function, we can make all creators uninstantiable and unusable by client code. This creator base could then additionally provide the derived instantiable singleton class needed by most creators, making it even easier for client code to write their own creators. -Jason

From: Jason Hise <chaos@ezequal.com>
Rob Stewart wrote:
with:
class make_me_a_singleton : public singleton_base { ... };
without:
class make_me_a_singleton { ... private: make_me_a_singleton() { }; ~make_me_a_singleton() { }; };
The first version is achievable just as easily with noninstantiable as with singleton_base. If singleton_base offers nothing more than noninstantiable, then the choice of names is debatable.
If you check the current version of the library, you will notice that 'singleton_base' offers a lot more than non-instantiable, specifically in the realm of control over the instance lifetime, dependency management between multiple singletons, and safety with regard to using singletons that have already been destroyed.
Then that clearly argues for putting the functionality in singleton_base and not a separate noninstantiable class (though that would be useful on its own).
To make the class instantiable by the framework, the supplied Creator policy class must have access to the ctor. You can make the ctor private and then make the Creator a friend, but then outside code can call creator<T>::create() to create an instance. If creator<T>::create() is private, and singleton<T> is a friend, then only singleton<T> can instantiate a T. That, of course, is a lot of machinery just to ensure that T can only ever be instantiated as a Singleton.
I agree, this might be a bit much machinery, especially because creator policies are likely to be written often by client code. However, there is a way to move all of the machinery into the library, so that client written creators don't have to re-implement it. Create and destroy are not static functions, as a creator must be allowed to have a saved state. These are just plain old member functions, and require a creator instance in order to be called. Thus, by adding a creator base with a pure virtual function, we can make all creators uninstantiable and unusable by client code. This creator base could then additionally provide the derived instantiable singleton class needed by most creators, making it even easier for client code to write their own creators.
IOW, if basic_singleton requires that the Creator template argument derive from creator_base, and creator_base uses a noninstantiable technique, then the client cannot create a Creator instance, so the only way to create an instance of type T is if T permits it. Provided that using basic_singleton<T> places no contrary burdens on T such that basic_singleton<T> controls (a) common, Singleton instance(s), yet other T's can be instantiated directly, it sounds good. Unfortunately, the functionality you described was provided by singleton_base suggests that this isn't the case. Am I missing something still? -- Rob Stewart stewart@sig.com Software Engineer http://www.sig.com Susquehanna International Group, LLP using std::disclaimer;

Rob Stewart wrote:
IOW, if basic_singleton requires that the Creator template argument derive from creator_base, and creator_base uses a noninstantiable technique, then the client cannot create a Creator instance, so the only way to create an instance of type T is if T permits it.
Exactly.
Provided that using basic_singleton<T> places no contrary burdens on T such that basic_singleton<T> controls (a) common, Singleton instance(s), yet other T's can be instantiated directly, it sounds good. Unfortunately, the functionality you described was provided by singleton_base suggests that this isn't the case.
Am I missing something still?
The functionality is provided in terms of a member class, called pointer. If T derives from singleton < T >, client code can use T::pointer instances to get at the singleton instance. If T does not derive from singleton < T >, client code must use singleton < T
::pointer instances to refer to the singleton instance.
-Jason

Jason Hise wrote:
Early on, I had the idea to disable creation of a user's singleton by making the base class have one pure virtual function. The user's derived singleton would become an abstract class, and thus not be able to be instantiated. Then the user would refer to the singleton via an even further derived class, like follows:
class singleton_base { private: virtual void define_to_enable_creation ( ) = 0; };
template < typename Type > class singleton : public Type { private: virtual void define_to_enable_creation ( ) { }
protected: // constructors and such were here
public: // interface was here };
//-------------------------------------------------
class test_singleton : public singleton_base { public: void do_something ( ); };
int main ( ) { test_singleton t; // this line would not compile singleton < test_singleton > t2; // neither would this singleton < test_singleton >::pointer ptr; // this would be the only access mechanism ptr->do_something ( );
return 0; }
I'm not really sure what the _goal_ of this is, but let's say * You want the client code to be able to derive from your singleton_base. * There should only be one instance ever of singleton_base or a derived class. * You want to protect against accidental instantiations. Then what's wrong with the client code implementing a factory function, e.g. in terms of a generic one? class singleton_base { protected: singleton_base() {} template< class Derived > static singleton_base& instance_() { static Derived theInstance; return theInstance; } public: // whatever. static singleton_base& instance(); // Impl. by client. }; Hth., - Alf

Jason Hise wrote:
let out would almost certainly ensure an 'A' in the class. Of course, if this is impossible I'll understand. I just thought I'd ask. :)
It seems unlikely because of the number of libraries in the review queue and the fact that reviews seem to be put on hold leading up to a release. But I guess it's possible. Jonathan
participants (11)
-
Alf P. Steinbach
-
Dan Rosen
-
David Abrahams
-
Edward Diener
-
Jason Hise
-
Jody Hagins
-
Jonathan Turkanis
-
Martin
-
Rob Stewart
-
Suman Cherukuri
-
Sérgio Vale e Pace