Creo que todas las respuestas anteriores han perdido de vista el bosque por los árboles.
Los genéricos de Java no son lo mismo que las plantillas ; usan el tipo de borrado , que es una técnica dinámica , en lugar de compilar el polimorfismo de tiempo , que es una técnica estática . Debería ser obvio por qué estas dos tácticas muy diferentes no funcionan bien.
En lugar de intentar usar una construcción en tiempo de compilación para simular una en tiempo de ejecución, veamos lo que extends
realmente hace: de acuerdo con Stack Overflow y Wikipedia , se usa extender para indicar subclases.
C ++ también admite subclases.
También muestra una clase de contenedor, que utiliza el borrado de tipo en forma de genérico, y se extiende para realizar una verificación de tipo. En C ++, debe hacer la maquinaria de borrado de tipo usted mismo, que es simple: haga un puntero a la superclase.
Vamos a envolverlo en un typedef, para que sea más fácil de usar, en lugar de hacer una clase completa, y listo:
typedef std::list<superclass*> subclasses_of_superclass_only_list;
Por ejemplo:
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
Ahora, parece que List es una interfaz, que representa una especie de colección. Una interfaz en C ++ sería simplemente una clase abstracta, es decir, una clase que implementa nada más que métodos virtuales puros. Con este método, podría implementar fácilmente su ejemplo de Java en C ++, sin ningún concepto o especialización de plantilla. También funcionaría tan lento como los genéricos de estilo Java debido a las búsquedas de tablas virtuales, pero esto a menudo puede ser una pérdida aceptable.