简体   繁体   中英

Inheritance issues with template classes

I'm having issues with a very strange error in some code I wrote. The basic idea behind the code can be trivialised in the following example:


template <class f, class g> class Ptr;

template <class a, class b, class c = Ptr<a,b> > class Base { public: Base(){}; };

template <class d, class e> class Derived : public Base <d,e> { public: Derived(){}; };

template <class f, class g> class Ptr { public: Ptr(){}; Ptr(Base<f,g,Ptr<f,g> >* a){}; };

typedef Derived<double,double> DDerived;

int main() { Base<int,int> b = Base<int,int>(); Derived<double,double> d = Derived<double,double>(); DDerived dd = DDerived(); Ptr<double,double> p(&dd); return 1; }

The basic idea is that pointers are replaced by the Ptr class (This will eventually be used in an MPI setting so standard pointers are effectively useless). The pointers are designed to 'point' at the base class, and so can point at any inherited class (as demonstrated in the example).

Can anyone think of any reason this might not work in a non-trivial case (But a case where the object architecture remains identical).

The error that is occurring in the main case is as follows:


void function()
{
  vector nVector(1);  // cut down for simplicity
  nVector[0].SetId(1); // To ensure the node is instantiated correctly
  Ptr temp(&nVector[1]);
};

This code produces the (slightly extended version of the) error when compiled with MPICXX:
no matching function for call to Ptr&lt;double, double>::Ptr(Derived&lt;double, double>*)
candidates are. . . (Some removed for simplicity's sake)
Ptr&lt;f, g>::Ptr(Base&lt;f, g, Ptr&lt;f, g> >*) [with f = double, g = double]

Cheers, Ed

EDITED (Detailing the error a little better, added info on the compiler)

Unfortunately, I was being slightly stupid and had forgotten to put my Ptr class in the same namespace as the Base and Derived classes.

That, I guess, would be why it wasn't working ! =]

Ok what about this:

class BasePtr
{
public:
    virtual void* obj() = 0;
};

template <class T>
class Ptr :: public BasePtr
{
public:
    Ptr() : ptr(0) {};
    Ptr(T* a) : ptr(a) {};
    virtual T* obj() { return ptr; }
protected:
    T* ptr;
};

Use BasePtr in the Base class but pass it the correct template object when Base needs to use it.

template <class a, class b >
class Base
{
public:
    Base(){};
    void set_ptr( BasePtr* );
};

DDerived dd = DDerived();
Ptr<double,double> p(&dd);
dd.set_ptr( p );

I still do not quite understand your problem but I hope that helps.

Try to use template template parameter instead of default value.

template <class a, class b, template <class aa, class bb> class c = Ptr >
class Base
{
typedef Ptr<a, b> pointer;
public:
    Base(){};
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM