creo que la terminología exacta para lo que necesita es "covarianza de plantilla", lo que significa que si B hereda de A, entonces de alguna manera T<B>
hereda de T<A>
. Este no es el caso en C++, ni lo es con los genéricos Java y C# *.
Hay una buena razón para evitar la covarianza de la plantilla: esto simplemente eliminará todo tipo de seguridad en la clase de plantilla. Voy a explicar con el siguiente ejemplo:
//Assume the following class hierarchy
class Fruit {...};
class Apple : public Fruit {...};
class Orange : public Fruit {...};
//Now I will use these types to instantiate a class template, namely std::vector
int main()
{
std::vector<Apple> apple_vec;
apple_vec.push_back(Apple()); //no problem here
//If templates were covariant, the following would be legal
std::vector<Fruit> & fruit_vec = apple_vec;
//push_back would expect a Fruit, so I could pass it an Orange
fruit_vec.push_back(Orange());
//Oh no! I just added an orange in my apple basket!
}
En consecuencia, se debe considerar T<A>
y T<B>
tipos que no guardan relación alguna, independientemente de la relación entre A y B.
Entonces, ¿cómo puede usted solucionar el problema que' mirando hacia atrás? En Java y C#, se puede usar respectivamente comodines acotadas y limitaciones:
//Java code
Bar(Container<? extends Interface) {...}
//C# code
Bar<T>(Container<T> container) where T : Interface {...}
El próximo C++ estándar (conocido como C++ 1x (antes C++ 0x)) inicialmente contenía una aún más potente mecanismo denominado Concepts, que habría permitido a los desarrolladores aplicar requisitos sintácticos y/o semánticos en los parámetros de la plantilla, pero desafortunadamente se pospuso a una fecha posterior. Sin embargo, Boost tiene un Concept Check library que puede interesarle.
Sin embargo, los conceptos pueden ser un poco excesivos para el problema que encuentre, y usar una simple afirmación estática como la propuesta por @gf es probablemente la mejor solución.
* Actualización: desde .NET Framework 4, es posible marcar los parámetros genéricos ha sido covariant or contravariant.
Las plantillas no son polimórficas. Las plantillas están vinculadas en tiempo de compilación, a diferencia de los objetos polimórficos que están vinculados en tiempo de ejecución. –
Preguntas relacionadas: http://stackoverflow.com/questions/1289167/template-polymorphism-not-working http://stackoverflow.com/questions/639248/c-covariant-templates –