2011-06-04 28 views
5

Tengo un problema con la conversión implícita, las plantillas y la herencia de las clases de la plantilla. Lo siguiente es lo que extraje de mi proyecto, he omitido que algunas clases son abstractas, pero no tiene que ver con el caso.Versión implícita de la clase derivada de la clase base de la plantilla

class A {}; 
class B : public A {}; 

template <typename T> class Base {}; 
class Derived : public Base<B> {}; 

int main() { 
    Derived d; 
    Base<A>* base = new Derived(); 
} 

Básicamente, tengo una clase base de la plantilla Base que derivo de Derived : public Base<B>. Luego tengo que convertirlo a la forma más general de Base, que es Base<A>.

yo habría pensado que puedo lanzar un objeto procedente Base<B>-Base<A> implícitamente, como se deriva de BA. ¿Estoy haciendo algo mal o cómo podría lanzar ese implícitamente? Esto es importante ya que necesito aceptar todos los tipos de clases derivadas en un método de Base como un parámetro .

Gracias de antemano.

Respuesta

6

Esto no es posible. Base<A> tiene ningún relación con Base<B>, independientemente de la relación entre A y B.

+0

Bueno, gracias. ¿Cómo intentaría arreglar eso? ¿Consideraría boost :: any como una opción? – opatut

+0

@opatut: considere usar una plantilla para su método. Sin más información, eso es todo lo que puedo sugerir. – Puppy

+0

Parece que la plantilla funciona, aunque no puedo verificarla usando static_assert (std :: is_base_of (...)), pero eso no es demasiado importante de todos modos. – opatut

2

Base<B> no necesariamente tienen que tener una relación con Base<A>. Esto no tiene nada que ver con Derived. Si quieres forzar esa relación, vas a necesitar un constructor con plantilla.

template <typename T> 
class Base 
{ 
    template <typename TOther> 
    Base(const TOther& that) 
    { 
     // ... 
    } 
    // ... 
}; 

Obviamente, la aplicación tendría que depender de la aplicación real de Base. Tenga en cuenta que este constructor no sustituye al constructor de copia normal.

+0

Esto no funcionará ya que la clase "Base" será parte de un motor, y "Otro" será parte de la aplicación real. Gracias de cualquier manera. – opatut

+0

No le dirá cómo diseñar su código, pero no hay ninguna razón para que ese constructor con plantilla no pueda estar en su archivo de encabezado y simplemente llamar a una función oculta que hace el trabajo real. –

+0

"No quiero decir cómo diseñar tu código" oh, es mejor que - me confundí con todas esas plantillas, así que realmente olvidé cómo funcionan. Lo siento: D Consideraré su respuesta como una opción. – opatut

Cuestiones relacionadas