Multiple inheritance from a template class

I am having problems with multiple inheritance from different instances of the same template class. In particular, I am trying to do this:

template <class T>
class Base
{

public:

    Base() : obj(NULL)
    {
    }

    virtual ~Base()
    {
        if( obj != NULL ) delete obj;
    }

    template <class T>
    T* createBase()
    {
        obj = new T();

        return obj;
    }

protected:

    T* obj;

};

class Something
{
    // ...
};

class SomethingElse
{
    // ...
};

class Derived : public Base<Something>, public Base<SomethingElse>
{

};

int main()
{
    Derived* d = new Derived();
    Something* smth1 = d->createBase<Something>();
    SomethingElse* smth2 = d->createBase<SomethingElse>();

    delete d;

    return 0;
}

When I try to compile the above code, I get the following errors:

1>[...](41) : error C2440: '=' : cannot convert from 'SomethingElse *' to 'Something *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>        [...](71) : see reference to function template instantiation 'T *Base<Something>::createBase<SomethingElse>(void)' being compiled
1>        with
1>        [
1>            T=SomethingElse
1>        ]
1>[...](43) : error C2440: 'return' : cannot convert from 'Something *' to 'SomethingElse *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

The problem seems ambiguous because the obj member is inherited from both Base <SomethingElse> and Base <SomethingElse>, and I can get around it by eliminating the ambiguous createBase calls:

Something* smth1 = d->Base<Something>::createBase<Something>();
SomethingElse* smth2 = d->Base<SomethingElse>::createBase<SomethingElse>();

However, this solution is terribly impractical, syntactic, and I would prefer something more elegant. Moreover, I am puzzled by the first error message. It seems to be implied that there is an instance of createBase <SomethingElse> in Base <Something>, but how is this possible? Any information or advice on this would be greatly appreciated.

+3
2

, Base< Something > createBase< SomethingElse >, ?

, createBase<T>() - -- ( T T ).

- :

// in Derived, or you could make some class (eg. MultiBase) for it

template <class T>
T* createBase()
{
  return Base<T>::createBase();
}
+2

" " - :

template<class T> T* Derived::Base<Something>::createBase<T>();

, , createBase() . , , "" .

, Derived ( ) Base<Something>::createBase(), Base<SomethingElse>::createBase().

jpalecek , :

Base<Something> * pBase = new Derived();
pBase->createBase();

static_cast<Base<Something> >(d)->createBase();

, jpalecek,

static_cast<Base<T> >(this)->createBase(); 

, ; , this Base<T>

0

Source: https://habr.com/ru/post/1746481/


All Articles