0

I have a rather complicate singleton template starting with

template <class T>
class Singleton {
 public:
    static T& GetInstance(){
    static T instance;
    return instance;
}
 private:
    Singleton() {}
    ~Singleton() = default; 
};

and then

class Class2;

template <class T>
class Class1{
  void sayHi();
};

using Class1Singleton= Singleton<Class1<Class2>>;

So you can see I have a singleton of Class1 (that is also template based so I use Class2 for that).

Then in another part of the code I have

Class1Singleton & anObject= Class1Singleton::GetInstance();

When I try to build this I get this error

error: invalid initialization of reference of type 
‘Class1Singleton& {aka Singleton<Class1<Class2> >&}’ 
from expression of type ‘Class1<Class2>’
         Class1Singleton::GetInstance();
                                       ^

Why is the Singleton being ignored??

KansaiRobot
  • 7,564
  • 11
  • 71
  • 150
  • 2
    I think you want `Class1& anObject= Class1Singleton::GetInstance();`. – songyuanyao Nov 30 '20 at 09:22
  • `Singleton>` returns a reference to `Class1`. Why do you think you should be able to initialize a reference of type `Singleton>&` by an object of type `Class1`? – Daniel Langr Nov 30 '20 at 09:28
  • @DanielLangr What? Could you elaborate please? How can I return the singleton? – KansaiRobot Nov 30 '20 at 09:30
  • @songyuanyao in that case, would `anObject` be a singleton? – KansaiRobot Nov 30 '20 at 09:31
  • 1
    @KansaiRobot Your `Singleton::GetInstance()` returns a reference to an object of type `T`, not of type `Singleton`. In you case, `T` is `Class1`. This: `Class1Singleton & anObject = Class1Singleton::GetInstance();` translates to `Singleton> & anObject = ` _a reference to an object of type `Class1`. – Daniel Langr Nov 30 '20 at 09:34
  • @DanielLangr I see. I have two questions: 1) Is the return object reference a singleton? 2) If not, how can I return a singleton? – KansaiRobot Nov 30 '20 at 09:36
  • See: https://stackoverflow.com/a/1008289/580083 or https://stackoverflow.com/a/271104/580083. Also related: https://stackoverflow.com/q/5739678/580083. – Daniel Langr Nov 30 '20 at 09:37

1 Answers1

0

You have:

template <class T>
class Singleton {
public:
    static T& GetInstance();
};
Singleton<T>& anObject = Singleton<T>::GetInstance();
//                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type is T&
//^^^^^^^^^^^ type is Singleton<T>&

The types don't match up. You are trying to initialize a reference to Singleton<T> with a reference to T.

You ask in the comments, "how can I return a singleton?". If you really want to return a Singleton<T> you can:

template <class T>
class Singleton {
public:
    static Singleton<T>& GetInstance() {
        // ^^^^^^^^^^^^^ return the type you want to return
        static Singleton<T> instance;
        return instance;
    }
 private:
    Singleton() = default;
    ~Singleton() = default; 
};
Jeff Garrett
  • 5,863
  • 1
  • 13
  • 12
  • Thanks!. One more question: If I get the singleton in a variable say `anObject', is there a way to access the methods of `Class1` from there? like how to call `sayHi()` from the singleton? – KansaiRobot Dec 01 '20 at 01:10
  • 1
    The `Singleton` you've got so far doesn't have a `T` in it. If `Singleton` contained a `T` and you had an accessor to a reference to that `T`, you could call methods. Alternatively, keep `GetInstance` returning a `T&` which is more useful, but didn't seem to be what you wanted to do. – Jeff Garrett Dec 01 '20 at 01:36