jeudi 6 mai 2021

C++ map of string to custom class with generics

I have tried in the past days to solve this issue I have with C++. It may be trivial, but I could not find a solution and searching on the Internet I still got nowhere, so I'll ask here.

I have a C++ wrapper Singleton class, a superclass and a number of subclasses. I need the the instances of the subclasses to be singletons, and so I used the solution proposed here as it is the one fitting my needs the most. I need a map to act as a register from a string to the correct subclass. To make it concrete here is the code:

// The Singleton class
template <typename T>
class Singleton
{
public:
    static T* Instance()
    {
        if (s_instance == NULL) { s_instance = new T(); }
        return s_instance;
    }
protected:
    static T* s_instance;
}

// Superclass
class MySuperclass
{
public:
    inline LPCSTR GetName() { return m_name; }
    
    virtual ~MySuperclass() { }
protected:
    LPCSTR m_name;
    
    MySuperclass(LPCSTR name) { m_name = name; }
}

// Example subclass
class MySubclass : public MySuperclass
{
    // subclass stuff
}

Now, I tried a number of thing, let me show all what I tried

// Where the problems begin
class MyRegister
{
public:
    static void Register()
    {
        Singleton<MySubclass> mySubclassSingleton;
        LPCSTR name = Singleton<MySubclass>::Instance()->GetName();
        s_classes.insert(std::make_pair(name, mySubclassSingleton));
    }
private:
    static std::unordered_map<LPCSTR, Singleton<MySuperclass>> s_classes;
}

This is the version I'm stuck with and it gives an error on the insert saying:

E0304 no instance of overloaded function "std::map<_Kty, _Ty, _Pr, _Alloc>::insert [with _Kty=LPCSTR, _Ty=Singleton<MySuperclass>, _Pr=std::less<LPCSTR>, _Alloc=std::allocator<std::pair<const LPCSTR, Singleton<MySuperclass>>>]" matches the argument list

I have tried using std::pair instead of std::make_pair, change the definition of the map to:

template <class T : public MySuperclass>
std::unordered_map s_classes<LPCSTR, Singleton<T>> s_classes;

But to no avail, as the first resulted in the same error (also using the [] operator gave me issues with [name] as no operator matches these operands) and the second results in type errors.

As it stands, I need the classes to be singletons, and to ensure they are singletons and I need a register that links a unique string identifying the class to it's singleton. Can anyone either explain why this is impossible or if there is something like Java's <? extends MySuperclass> in C++ that can work here?

Aucun commentaire:

Enregistrer un commentaire