2

I implemeted a template singleton class along with static member definition:

template <typename T> class SingletonT
{
public:
    static T *GetInstance()
    {
        if (!s_instance)
        {
            s_instance = new T;
        }
        return s_instance;
    }
private:
    static T *s_instance;
};
template <typename T> T *SingletonT<T>::s_instance = 0;

It compiles fine and works fine. Now, I'm trying to create a singleton that will use custom function instead of operator new:

template <typename T, T *(*f)()> class PolymorphSingletonT
{
public:
    static T *GetInstance()
    {
        if (!s_instance)
        {
            s_instance = f();
        }
        return s_instance;
    }
private:
    static T *s_instance;
};
template <typename T, T *(*f)()> T *PolymorphSingletonT<T, T *(*f)()>::s_instance = 0;

I get a compile error on the last line saying error C2146: syntax error : missing ')' before identifier 'f'

I use MSVC2005 compiler.

Update Now I ended up with functor approach:

template <typename T, typename F> class PolymorphSingletonT
{
public:
    static T *GetInstance()
    {
        if (!s_instance)
        {
            s_instance = F::Create();
        }
        return s_instance;
    }
private:
    static T *s_instance;
};
template <typename T, typename F> T *PolymorphSingletonT<T, F>::s_instance = 0;

However, it forces me to wrap my creation function with a functor. It only adds a couple of code lines and works perfectly, but anyway I'm still interested in getting it without functors.

Nick
  • 3,205
  • 9
  • 57
  • 108
  • Read: http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 – Martin York Nov 24 '12 at 17:18
  • Using pointers is a bad idea for singeltons. Return a reference. Also you need to deal with destruction of the singelton. – Martin York Nov 24 '12 at 17:19
  • @LokiAstari The `instance` function should definitely return a reference, since it guarantees that it won't return a null pointer. For the implementation, it's less clear, and I generally prefer a pointer, in order to avoid destructing the object (and creating an order of destruction problem). – James Kanze Nov 24 '12 at 18:02
  • @LokiAstari I might add that the solution proposed in the article you reference is not thread safe in C++03. (But there are fairly simple ways to make it thread safe.) – James Kanze Nov 24 '12 at 18:03
  • @JamesKanze: The article lineked has links (with solutions) for both threading and order of destruction. **BUT** It is an over-simplified example. Singelton is not a pattern that should be used in isolation (as you hint at). Much better to use some sort of factory (or initialization pattern) so that you can customize for debug and/or unit testing etc. – Martin York Nov 24 '12 at 20:05

1 Answers1

3

The last line should be:

template <typename T, T *(*f)()> T *PolymorphSingletonT<T,f>::s_instance = 0;

Don't repeat the type signature, use the names you've specified.

Mat
  • 202,337
  • 40
  • 393
  • 406