template español c++ templates generics c++11 c++-concepts

template c++ español



¿En qué se diferencian los conceptos de las interfaces? (4)

¿En qué se diferencian los Conceptos (es decir, aquellos que se descartaron recientemente del estándar C ++ 0x) de las Interfaces en lenguajes como Java?


Es más o menos una diferencia en el punto de vista. Mientras que una interfaz (como en C #) se especifica de manera similar a una clase base, un concepto también puede combinarse automáticamente (similar a la tipificación de pato en Python). Aún no está claro a qué nivel C ++ va a ser compatible con la coincidencia automática de conceptos, que es una de las razones por las que lo abandonaron.


Los conceptos son interfaces implícitas. En C # o Java, una clase debe implementar explícitamente una interfaz, mientras que en C ++, una clase es parte de un concepto, siempre y cuando cumpla con las restricciones del concepto.

La razón por la que verá conceptos en C ++ y no en Java o C # es porque C ++ realmente no tiene "interfaces". En su lugar, puede simular una interfaz utilizando herencia múltiple y clases base abstractas, sin miembros. Esto es algo así como un truco y puede ser un dolor de cabeza para trabajar (por ejemplo, la herencia virtual y el problema del diamante ). Las interfaces juegan un papel crítico en la OOP y el polimorfismo, y ese rol no se ha cumplido adecuadamente en C ++ hasta ahora. Los conceptos son la respuesta a este problema.


Los conceptos son para el polimorfismo en tiempo de compilación, que significa código genérico paramétrico. Las interfaces son para el polimorfismo en tiempo de ejecución.

Tienes que implementar una interfaz al implementar un concepto. La diferencia es que no tiene que decir explícitamente que está implementando un concepto. Si la interfaz requerida coincide, entonces no hay problemas. En el caso de las interfaces, incluso si implementó todas las funciones requeridas, ¡tiene que decir con entusiasmo lo que está implementando!

Intentaré aclarar mi respuesta :)

Imagine que está diseñando un contenedor que acepta cualquier tipo que tenga la función de miembro de tamaño . Formalizamos el Concepto y lo llamamos HasSize, por supuesto que deberíamos definirlo en otro lugar, pero este ya no es un ejemplo.

template <class HasSize> class Container { HasSize[10]; // just an example don''t take it seriously :) // elements MUST have size member function! };

Luego, imagine que estamos creando una instancia de nuestro contenedor y lo llamamos myShapes , Shape es una clase base y define la función de miembro de tamaño . Square y Circle son solo hijos de ella. Si la Forma no define el tamaño, entonces debería producirse un error.

Container<Shape> myShapes; if(/* some condition*/) myShapes.add(Square()); else myShapes.add(Circle());

Espero que veas que Shape puede verificarse contra HasSize en tiempo de compilación , no hay razón para hacer la verificación en tiempo de ejecución. A diferencia de los elementos de myShapes , podríamos definir una función que los manipule:

void doSomething(Shape* shape) { if(/* shape is a Circle*/) // cast then do something with the circle. else if( /* shape is a Square */) // cast then do something with the square. }

En esta función, ¡no puedes saber qué pasará hasta el tiempo de ejecución de un Círculo o un Cuadrado!

Son dos herramientas para un trabajo similar, aunque la Interfaz, o como se llame, puede hacer casi el mismo trabajo de Concepts en tiempo de ejecución, ¡pero usted pierde todos los beneficios de la verificación y optimización en tiempo de compilación!


Los conceptos son tipos de Me gusta (clases) para plantillas: es solo para el lado de programación genérico del lenguaje.

De esa manera, no pretende reemplazar las clases de interfaz (suponiendo que se refiera a clases abstractas u otra implementación equivalente en C ++ de C # o Interfaces Java) ya que solo pretende verificar los tipos utilizados en los parámetros de plantilla para cumplir con los requisitos específicos. La verificación de tipo solo se realiza en tiempo de compilación como toda la generación de código de plantilla y mientras que las clases de interfaz tienen un impacto en la ejecución del tiempo de ejecución.