Je pense que toutes les réponses précédentes ont perdu de vue la forêt pour les arbres.
Les génériques Java ne sont pas les mêmes que les modèles ; ils utilisent l' effacement de type , qui est une technique dynamique , plutôt que le polymorphisme au moment de la compilation , qui est une technique statique . Il devrait être évident pourquoi ces deux tactiques très différentes ne gèlent pas bien.
Plutôt que d'essayer d'utiliser une construction au moment de la compilation pour simuler une construction au moment de l'exécution, regardons ce qui extends
fait réellement: selon Stack Overflow et Wikipedia , extend est utilisé pour indiquer le sous-classement.
C ++ prend également en charge le sous-classement.
Vous affichez également une classe de conteneur, qui utilise l'effacement de type sous la forme d'un générique, et s'étend pour effectuer une vérification de type. En C ++, vous devez effectuer vous-même la machine d'effacement de type, ce qui est simple: faites un pointeur vers la superclasse.
Emballons-le dans un typedef, pour le rendre plus facile à utiliser, plutôt que de créer une classe entière, et voilà:
typedef std::list<superclass*> subclasses_of_superclass_only_list;
Par exemple:
class Shape { };
class Triangle : public Shape { };
typedef std::list<Shape*> only_shapes_list;
only_shapes_list shapes;
shapes.push_back(new Triangle()); // Works, triangle is kind of shape
shapes.push_back(new int(30)); // Error, int's are not shapes
Maintenant, il semble que List soit une interface, représentant une sorte de collection. Une interface en C ++ serait simplement une classe abstraite, c'est-à-dire une classe qui n'implémente rien d'autre que des méthodes virtuelles pures. En utilisant cette méthode, vous pouvez facilement implémenter votre exemple java en C ++, sans aucun concept ni spécialisation de modèle. Il fonctionnerait également aussi lentement que les génériques de style Java en raison des recherches de table virtuelle, mais cela peut souvent être une perte acceptable.