Boost logo

Boost :

From: Jason Hise (chaos_at_[hidden])
Date: 2005-01-08 12:56:12


Dave Handley wrote:

> Providing an allocator template is essentially what is done in Loki so
> that would suffice to resolve this particular difference.

I have recently converted my code to CRTP form and noticed an inherent
problem with creating an allocator template now. Because the derived
class is the final singleton class, and its ctor and dtor are protected,
there is no way to give a generic allocator the right to create the
object. Even attempting to write a secret friendly shortcut through the
base can't work, because the base doesn't have access to its children's
protected members. I'm trying to use the template specialization method
that Herb Sutter mentions in Exceptional C++ Style #15, putting
protected templated functions in the base and then specializing the
child versions to get access to the ctor. Unfortunately, all my
attempts have failed. Here is a stripped down example of what I am
trying (destruction would be virtually identical, and thus is omited):

template < typename T >
class AllocateUsingNew
{
public:
    static T * Create ( )
    {
        T * p = reinterpret_cast < T * > ( new char [ sizeof ( T ) ] );
        try
        {
            return T :: Allocation :: Construct ( p );
        }
        catch ( ... )
        {
            delete [] reinterpret_cast < char * > ( p );
            throw;
        }
    }
};

template < typename T, typename A = AllocateUsingNew < T > >
class Singleton
{
public:
    class Allocation
    {
    private:
        friend A; // allow the allocator access to Allocation::Create

        static void Create ( T * p )
        {
            T :: Create < T > ( p ); // call the derived specialization?
        }
    };

    friend Allocation; // allow allocation access to Create

protected:
    template < typename T >
    static void Create ( T * p ); // undefined base template that
derived should inherit
};

template < typename T >
void T :: Create < T > ( T * p ) // specialize derived's Create method?
{
    new ( p ) T;
}

Any suggestions?

> Sorry, I think you have misunderstood me. I know that the
> dependencies method can be used in different ways, but it is still
> only a single policy. The reason for providing completely different
> policies for the lifetime policy is just that different projects
> require different solutions. I know for example that the dependencies
> model would fall down very quickly in the system I code in at
> present. We have a singleton that is the root of the tree that
> contains all the data in the system. Everyone uses this singleton,
> but doesn't tend to hold out references (dependencies). Under your
> dependency model, we would be almost forced to place a dependency in
> the main function - but here lies the problem. We actually have a
> number of different products which share the code base, but provide
> different main functions (and a few key interface classes) - this
> would mean we are coupling the main singleton to loads of places in
> the code. Using lifetimes, we can trivially make sure that this is
> the last singleton to come down.

Or... you could just add a static dependency to that specific singleton
in the code where the singleton is defined ;)

> I'm not saying dependencies are wrong - I'm just saying that a generic
> implementation should really provide the choice. I prefer to use
> longevities - you clearly prefer the dependencies - other people
> prefer to use Phoenix Singletons (singletons that re-create themselves
> from their own ashes if they are re-accessed after destruction).

Alright, I can accept that there may be different lifetime models that
are needed. The phoenix singleton, however, is already handled by my
current model, which attaches a dependency to the smart singleton
pointer when GetInst is called. Unfortunately, I have been looking at
the Loki singleton code (hopefully the book will get here soon), and am
having trouble seeing how a dependency model could be implemented with
Loki's lifetime traits model. Could you give me an example of how this
could be achieved?

-Jason


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk