3

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)

5
  • +1 for making the effort of reducing the code to its simplest form. Commented Feb 25, 2009 at 13:39
  • Can you tell us more about the strange error you're seeing? Commented Feb 25, 2009 at 13:50
  • And what is the compiler you are using? Commented Feb 25, 2009 at 18:23
  • Your error-causing code seems to have been eaten by SO... but I'm not having issues with std::vector<Base<double, double> > (VC++9), so it may be some weirdness with the underlying C++ compiler (g++?). Commented Feb 27, 2009 at 5:27
  • Not a compiler error as far as I can tell -> the code I gave compiles fine but the higher-level version doesn't. Commented Feb 27, 2009 at 16:12

3 Answers 3

1

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 ! =]

Sign up to request clarification or add additional context in comments.

Comments

0

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(){};
};

1 Comment

Erm. . . This doesn't compile and I'm not really sure what you're getting at? You seem to be trying to define a class inside a template argument.
0

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.

3 Comments

Unfortunately impossible in the more complex scenario, as it ends up with a recursive template definition: template <class A, class B, class c = Ptr<A,B,Ptr<A,B . . . > > This is not an option, although it was the original design.
Second revision: I understand your idea but it's not an option, the template argument is for a typedef, and so cannot be allocated after instantiation with a method. The templated argument is used to override the standard Ptr object with an MpiPtr when the code is used in a distributed fashion.
Why can't MpiPtr derived from BasePtr?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.