Проблемы наследования с шаблонными классами - PullRequest
3 голосов
/ 25 февраля 2009

У меня проблемы с очень странной ошибкой в ​​коде, который я написал. Основная идея кода может быть упрощена в следующем примере:

<code>
template <class f, class g> class Ptr;</p>

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

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

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

<p>typedef Derived<double,double> DDerived;</p>

<p>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;
}
      

Основная идея состоит в том, что указатели заменяются классом Ptr (это в конечном итоге будет использоваться в настройке MPI, поэтому стандартные указатели будут фактически бесполезны). Указатели предназначены для «указания» на базовый класс и поэтому могут указывать на любой унаследованный класс (как показано в примере).

Может кто-нибудь придумать, по какой причине не может работать в нетривиальном случае (но в случае, когда архитектура объекта остается идентичной).

Ошибка, возникающая в основном случае, выглядит следующим образом:

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

Этот код выдает ошибку (слегка расширенную версию) при компиляции с MPICXX:
нет соответствующей функции для вызова Ptr&lt;double, double>::Ptr(Derived&lt;double, double>*)
кандидаты есть. , , (Некоторые из них удалены для простоты)
Ptr&lt;f, g>::Ptr(Base&lt;f, g, Ptr&lt;f, g> >*) [with f = double, g = double]

Cheers, Ed

РЕДАКТИРОВАНИЕ (Детализация ошибки немного лучше, добавлена ​​информация о компиляторе)

Ответы [ 3 ]

1 голос
/ 27 февраля 2009

К сожалению, я был немного глуп, и забыл поместить свой класс Ptr в то же пространство имен, что и классы Base и Derived.

Наверное, поэтому это не сработало! =]

0 голосов
/ 25 февраля 2009

Попробуйте использовать параметр шаблона шаблона вместо значения по умолчанию.

template <class a, class b, template <class aa, class bb> class c = Ptr >
class Base
{
typedef Ptr<a, b> pointer;
public:
    Base(){};
};
0 голосов
/ 25 февраля 2009

Хорошо, как насчет этого:

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;
};

Используйте BasePtr в базовом классе, но передайте ему правильный шаблонный объект, когда Base должен его использовать.

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 );

Я до сих пор не совсем понимаю вашу проблему, но надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...