Singleton and constructors with arguments

Hi all,
this is my first post and I hope this is going to be an easy one.

I inherited well written but zero-commented code. And I was trying to understand how a particular piece of code works... 'cause it works perfectly.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
template <class T> class Singleton {

  private:
    Singleton(){;}
    static T* theInstance;

  public:
    static T* GetInstance() {
      if ( theInstance == NULL ) {
        theInstance = new T();
      }
      return theInstance;
    }
    template <class C> static T* GetInstance( C val ) {
      if ( theInstance == NULL ) {
        theInstance = new T(val);
      }
      return theInstance;
    }
    template <class C, class M> static T* GetInstance( C val1, M val2 ) {
      if ( theInstance == NULL ) {
        theInstance = new T(val1, val2);
      }
      return theInstance;
    }

};

template <class T>  T* Singleton<T>::theInstance = NULL;


You can use singleton in this way:
 
MyClass *aClass_ptr = Singleton<MyClass>::GetInstance();


or

 
MyClass *aClass_ptr = Singleton<MyClass>::GetInstance(val1);



or

 
MyClass *aClass_ptr = Singleton<MyClass>::GetInstance(val1, val2);


The point is: how the singleton knows about MyClass-constructor arguments-type?

Again: it works perfectly (and I've personally overloaded the version with 2 arguments!), but I do not understand how! :D

Many many thanks in advance!

Cheers,
Marco
Did you compile after you overloaded the constructors?
Hmm I guess it gives you a couple of compiler errors as you made the overriding constructors inline but you coded them as you are coiding outside.
Still I am not able to understand what you want to achieve here.

Nested or template overloading kind of???
I compiled and run the program and it worked perfectly. I used a 'people' class, whose data members are a _name (std::string) and a _height (int). I defined 2 kinds of constructor:
people();

people( std::string, int );

I created one 'people' in this way:
 
people* aPerson = Singleton<people>::GetIstance();

but (in another program, 'cause the Singleton do works) also in this way:
 
people* aPerson = Singleton<people>::GetIstance( "Mark", 166 );

And it gives me no error at all

What I want is to have a Singleton that works for constructors taking one or more arguments.

Thanks for being giving a look!

Marco
Templates are replaced during compile time. The compiler will map the functions of the specific class to the generics.

The template class does not know nor even need to know the pre-conditions of your specific class. The compiler does this job. Try violating the pre-conditions and the compiler will complain.
The code in the original post will work for constructors that take zero, one, or two parameters. Under the current C++ standard there is no way to generalize the solution for N parameters (however in the next version of the standard variadic templates will solve the problem).

The way the problem is typically solved today is to provide a bunch of templated functions that cover enough parameters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// This one works for constructors that take exactly 1 parameter
template< typename T, typename P1 >
static T* GetInstance( const P1& p1 ) { ... }

// This one works for constructors that take exactly 2 parameters
template< typename T, typename P1, typename P2 >
static T* GetInstance( const P1& p1, const P2& p2 ) { ... }

// ...etc...
template< typename T, typename P1, typename P2, typename P3, typename P4,
                   typename P5, typename P6, typename P7, typename P8, typename P9 >
static T* GetInstance( const P1& p1, const P2& p2, const P3& p3, const P4& p4,
                                       const P5& p5, const P6& p6, const P7& p7, const P8& p8,
                                       const P9& p9 ) { ... }

// ...etc... 
Thank you all guys! Now it is much more clear.
BTW, I discovered another case in which you can use templated methods w/o explicitely specifying type-arguments, the std::sort method:

1
2
3
4
5
template <class RandomAccessIterator>
  void sort ( RandomAccessIterator first, RandomAccessIterator last );

template <class RandomAccessIterator, class Compare>
  void sort ( RandomAccessIterator first, RandomAccessIterator last, Compare comp );


http://www.cplusplus.com/reference/algorithm/sort.html
Topic archived. No new replies allowed.