2011-11-02 22 views
6

Hola y buen día para ti.C++: fuerza compilación de plantilla completa (MSVC/G ++)

fragmento de código siguiente se compila en cl.exe (15.00.30729.01) y MinGW-g ++ (4.4.0):

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     int doesNotExist = 6; 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

int main(int argc, char** argv){ 
    Test<int> test; 
    return 0; 
} 

Además, en cl.exe que incluso puede salirse con algo como esto:

template<typename T> class Test{ 
public: 
    T t; 
    void error(){ 
     doesNotExist = 6;//<---- undeclared variable 
     return doesNotExist;//<---- void function returning result 
    } 
}; 

Ahora, esto obviamente sucede porque el compilador no crea contenidos para los métodos de una clase de plantilla hasta que alguien los llama. Sin embargo, esto puede plantear problemas cuando diseñas una clase de plantilla grande (porque es muy probable que olvides agregar una llamada de prueba al nuevo método en alguna parte).

La pregunta:
¿Hay un modificador de compilador de g ++ o cl.exe que obligaría compilador para procesar toda la plantilla (por lo que este fragmento de código se disparará error de compilación)?

Respuesta

11

Si desea probar la plantilla con un par de tipos, puede desencadenar ejemplificaciones manuales de los tipos, como en:

// at namespace level 
template class Test<int>; 

instanciaciones explícitas de plantillas de clase desencadenar automáticamente la creación de instancias de todos los miembros, que parece ser lo que quieres

El problema real es que el lenguaje está diseñado para permitir explícitamente el comportamiento que desea evitar. Cuando se crea una instancia implícita de una plantilla de clase, el compilador instanciará solo los métodos que son utilizados. El caso de uso principal de la característica es que algunos métodos pueden imponer requisitos más estrictos que otros en el tipo de creación de instancias, si todos los métodos se instanciaron siempre, entonces la plantilla de clase solo se podría usar con los tipos que cumplan los requisitos más estrictos.

Al permitir que el compilador solo instancia los métodos que se utilizan, la plantilla de clase se puede utilizar con tipos que no cumplen todos los requisitos de todos los métodos, siempre que cumplan con los requisitos de los métodos. que en realidad se usan.

Un ejemplo común es operator[] en std::map<> que requiere la value_type ser default-construible (operator[] va a crear un nuevo valor predeterminado objeto inicializa si la clave no está presente en el recipiente y devolver una referencia a la misma). El comportamiento en el lenguaje le permite usar std::map en tipos que no son predeterminado construible, siempre que no use operator[] (o cualquier otra función miembro que imponga ese requisito).

+2

Sí, la instanciación de plantilla explícita es lo que desea. También vea: http://msdn.microsoft.com/en-us/library/by56e477%28VS.80%29.aspx –

+0

Buena explicación del propósito real de no tener error de compilación. – iammilind

+0

Bien, funciona. Acepto tu respuesta, pero no fue realmente necesario explicar POR QUÉ funciona de esta manera (ya lo sabía). Gracias por la respuesta. – SigTerm

Cuestiones relacionadas