penso che la terminologia esatta per quello che ti serve è "template covariance", nel senso che se B eredita da A, allora in qualche modo T<B>
eredita da T<A>
. Questo non è il caso in C++, né con Java e C# generics *.
C'è una buona ragione per evitare la covarianza del modello: questo semplicemente rimuoverà tutti i tipi di sicurezza nella classe template. Mi spiego con il seguente esempio:
//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!
}
Di conseguenza, si dovrebbe considerare T<A>
e T<B>
tipi come completamente indipendenti, a prescindere dalla relazione tra A e B.
Così come si potrebbe risolvere il problema che si' stai di fronte? In Java e C#, è possibile utilizzare rispettivamente jolly limitati e vincoli:
//Java code
Bar(Container<? extends Interface) {...}
//C# code
Bar<T>(Container<T> container) where T : Interface {...}
La prossima C++ standard (nota come C++ 1x (ex C++ 0x)) inizialmente conteneva un ancora più potente meccanismo denominato Concepts, che avrebbe consentito agli sviluppatori di applicare requisiti sintattici e/o semantici sui parametri del modello, ma è stato purtroppo rimandato a data successiva. Tuttavia, Boost ha un Concept Check library che potrebbe interessarti.
Tuttavia, i concetti potrebbero essere un po 'eccessivo per il problema che si verifica, un utilizzo di un semplice asser statico come proposto da @gf è probabilmente la soluzione migliore.
* Aggiornamento: Dal .Net Framework 4, è possibile contrassegnare i parametri generici è covariant or contravariant.
I modelli non sono polimorfici. I modelli sono vincolati in fase di compilazione, a differenza degli oggetti polimorfici che sono vincolati in fase di esecuzione. –
Domande correlate: http://stackoverflow.com/questions/1289167/template-polymorphism-not-working http://stackoverflow.com/questions/639248/c-covariant-templates –