2012-09-11 21 views
5

Puede alguien dar una pista de cómo lo hace expresiones proceso compilador comoC++ análisis plantilla de la orden de código/CRTP

class DerivedA: public ParentTemplateClass<DerivedA>{ 
} 

Para mee que parece:

el padre de este niño es un "hijo" de este niño

Quiero decir que no es obvio para mí cómo se puede completar el "análisis sintáctico" de la clase DerivedA SIN conocer exactamente la "descripción" de la clase principal. Parece que no puede. Entonces la clase de padres debe procesarse antes que los niños, pero en tal situación, los padres dependen de los niños ... y estoy atrapado allí.

Sí, hay algunos artículos en la web que describen el uso de tal cosa, p. un artículo sobre el patrón de plantilla Curiosamente recurrente ( http://en.wikibooks.org/wiki/More_C++_Idioms/Curiously_Recurring_Template_Pattern), pero eso no es un tipo de estándar o algo cercano. Debe haber una descripción clara del comportamiento, como ordenar las operaciones, ¿no es así?

RESPUESTA: Thnx to everyone. Sí, la analogía del forward me parece legítima para dejar de dañar mi cerebro. Las plantillas siguen siendo un estado del arte para mí debido a su naturaleza sublengua oculta y no puedo solo g ++ -E :)

+1

Piénselo en este momento como si fuera una declaración directa. – PlasmaHH

+0

Pienso en esto como "El padre del chico se define en términos de este hijo específico."No soy fanático de CRTP, sospecho que se usa en exceso, pero la interpretación del código CRTP específico es relativamente sencilla. Las plantillas siempre se expanden por completo antes de que se puedan crear instancias de objetos tipeados. – aSteve

+0

" Las plantillas siempre se expanden completamente antes los objetos mecanografiados se pueden instanciar "sí, parece legítimo. Para mí, algún tipo de efecto de desenfoque se debe a que la temaplate se instancia durante la compilación y no en el preprocesamiento. – sohel

Respuesta

6

Después de que su código diga class DerivedA, se declara el símbolo DerviedA. En el punto, puede usarse como un parámetro de plantilla. Los compiladores de C++ hacen varias pasadas al código, por lo que en ese momento al analizar el compilador "creerá" que su intención era correcta y que eventualmente obtendrá la definición de esa clase (cuando se trata de crear una instancia de la plantilla, es decir, usted realmente usa ese tipo). Si no, se quejará en ese punto. Algo similar sucede si utilizó una clase declarada forward en una declaración pero no proporcionó una definición antes de usarla.

1

Creo que para entender cómo podría funcionar esto, también necesita comprender más acerca de las plantillas C++ en general, que solo el Patrón de Plantilla Curiosamente Recurrente. Alguien más puede probablemente responder esto mejor que yo, pero sé que C++ no puede analizar completamente una definición de clase de plantilla por sí mismo. Crea una instancia de la plantilla cada vez que se usa en el código. Si cada clase fue separada en un archivo de inclusión, pensar en ello como esto:

#include "ParentTemplateClass.h" // C++ initially validates the template class definition's syntax. 
#include "DerivedA.h" // First use of ParentTemplateClass - 
         // at this point it becomes fully instantiated. 

El analizador C++ será inicialmente validar la sintaxis de la plantilla cuando se ve la definición de plantilla. Luego, cuando la plantilla se usa como base de DerivedA, el análisis continúa y la plantilla está completamente instanciada. Esto es, por supuesto, una vista simplificada del análisis que hará el compilador de C++, y estoy seguro de que los detalles varían según el compilador. Vea también http://womble.decadent.org.uk/c++/template-faq.html#disambiguation.

3

En el punto en el que se crea una instancia de la plantilla, DerivedA es incompleto; ha sido declarado, pero no completamente definido. Los tipos incompletos se pueden usar de varias maneras; por ejemplo, puede declarar punteros o referencias a ellos, declarar funciones con ellos como retorno o tipos de parámetros, y algunas otras cosas. No puede crear objetos, heredar de ellos, acceder a sus miembros o, en general, hacer cualquier cosa que requiera más información que solo el nombre de la clase.

Siempre que la plantilla de clase solo haga estas cosas, no hay ningún problema.