2011-10-26 6 views
8

Duplicar posible:
Incomplete class usage in template¿Cuándo debe completarse un tipo utilizado como argumento de plantilla si se usa internamente en un contexto que requiere un tipo completo?

Tengo una pregunta que me ha sido desconcertante para un par de horas.

Al principio pensé que el tipo tendría que ser completa en el punto de instanciación, pero todos los compiladores que han intentado aceptar el tipo que aún estaba incompleta en ese momento, siempre que se define en cualquier lugar de la traducción unidad.

Para ilustrarlo, la cuestión es sobre la exactitud de este sencillo programa:

template <typename T> 
int size() { 
    return sizeof(T); // T is required to be complete in this expression 
} 
class test;   // test is declared, but incomplete 

int main() { 
    size<test>(); 
} 
// [1] point of instantiation of size<test>() 

class test {};   // Definition of test, now it is complete 

Según §14.6.4.1/1 el punto de instanciación de size<test> es la línea marcada como [1], y en ese punto, el tipo test aún está incompleto. Si hubiéramos intentado realizar la operación sizeof(test) allí, el compilador habría fallado diciéndonos que el tipo está incompleto. Y aún llamando a una plantilla dentro de la cual el tipo para realizar esa misma operación exacta se compila en g ++, clang ++, comeau y Visual Studio 2010.

¿El código anterior es realmente correcto? ¿En qué parte del estándar admite que el tipo utilizado como argumento para la plantilla se considere completo si es completo en cualquier lugar de la misma unidad de traducción? ¿O cuando debe estar completo?

+0

Pregunta muy similar: http://stackoverflow.com/questions/7210286 – aschepler

+0

@aschepler: Creo que son exactamente las mismas, la única diferencia, así que he votado para cerrar. No lo estoy eliminando (aún) para * aumentar * su pregunta y ver si alguien responde con una respuesta (la única respuesta a su pregunta es un poco). Gracias por señalar el duplicado. –

+0

@aschepler: definitivamente un duplicado, sin embargo, esta pregunta parece estar recibiendo más atención (la vida es injusta). Realmente me gustaría que nuestros estandaristas salten aquí. –

Respuesta

1

La plantilla no se compila hasta que se expande al final (la prueba está completa en ese momento).

+0

Acepto que esto es coherente con el comportamiento de esos compiladores, pero estoy tratando de determinar si esto es coherente con las normas de la norma o no. +1 de todos modos. –

+0

Ese sería el comportamiento de MSVC, pero desde un punto de vista estándar, hubiera esperado que la generación tuviera lugar en el primer punto de creación de instancias. –

+0

@MatthieuM .: Ese comportamiento es constante en todos los compiladores que he probado, por lo que no es solo MSVC. Alf Steinbach en el chat señaló las fases de la traducción y, en particular, a 2.2/8 que indica que la instanciación de la plantilla se realiza en una fase posterior que la traducción del código no con plantilla. Esto solo indica que * en el tiempo * la instanciación se realiza * después * de que se haya procesado toda la TU, aunque eso no significa que * en el espacio * no sea necesario completar el tipo antes del * punto de creación de instancias *. Lo he agregado como respuesta al duplicado. –

Cuestiones relacionadas