2012-01-20 5 views
5

Tengo un montón de código de plantilla. Como el código de la plantilla incorrecta no arroja un error de compilación a menos que esté compilado, ¿hay alguna forma de que pueda verificar qué funciones de plantilla el compilador realmente 'compiló' y cuáles fueron ignoradas por completo?¿Puedo verificar qué plantillas de funciones se han instanciado o no, al menos una vez?

EDIT 2:

Si un particular, plantilla de clase o plantilla de función se instancia una vez, para cualquier tipo de parámetros, a continuación, que está bien. Quiero la lista de plantillas de funciones/clases que nunca fueron instanciadas de ninguna forma.

Un ejemplo particular es el siguiente. Son dos funciones de plantilla distintas, y me gustaría saber si una o ambas nunca se crean instancias.

template <typename T_InputItr, typename T_Distance> 
void advance(T_InputItr& aItr, T_Distance aN, bidirectional_iterator_tag) 

template <typename T_InputItr, typename T_Distance> 
void advance(T_InputItr& aItr, T_Distance aN, random_access_iterator_tag) 

EDIT: Actualmente, para las clases, les instanciar en el archivo .cpp manualmente así:

template TClass<int>; 

para todos los tipos Me interesa Eso es así y bueno.. Pero eso es si recuerdo hacer eso. A veces necesito escribir muchas clases/funciones de plantillas pequeñas donde me olvido de crear una instancia de algunas de las plantillas de funciones/clases de forma manual y lo descubro más adelante. Me gustaría que el compilador me diga eso.

Alternativamente, si pudiera obtener la lista de plantillas de funciones/clases que se crearon instancias (para cualquier parámetro), entonces podría comparar eso con la lista completa que podría encontrar en el código.

Otro beneficio sería 'probar' qué métodos se compilaron en una clase de plantilla que utiliza rasgos de tipo para compilar selectivamente ciertas funciones. Quiero estar seguro de que mi lógica para seleccionar las funciones correctas es correcta antes de continuar.

+0

¿Y qué harías si pudieras comprobarlo? – Jon

+0

@Jon: Lo probaría instanciando manualmente con tipos ficticios para asegurarme de que su sintaxis es correcta, al menos para los tipos que sé que puede tomar. – Samaursa

+0

Así que ahí está su respuesta: haga un proyecto de prueba donde invoque * todas * funciones con plantillas con * todos * tipos que sabe que pueden tomar. Si el proyecto no se compila, tienes un problema. :) – Jon

Respuesta

1

Alguien mencionó que "todo puede ser resuelto mediante la adición de un nivel de indirección" - se puede añadir una aserción estática para cada función y ver la compilación falle:

template <typename T> 
struct Asserter 
{ 
    static const bool value = false; 
}; 

template <typename T> 
struct Foo 
{ 
    void foo() 
    { 
    static_assert(Asserter<T>::value, "Foo::foo() is being compiled."); 
    } 
    void bar() 
    { 
    static_assert(Asserter<T>::value, "Foo::bar() is being compiled."); 
    } 
}; 

int main() 
{ 
    Foo<int> f; 
    //f.foo(); // static assertion! 
} 

Si no quieren a la compilación romper en cada paso, en su lugar puede emitir un Boost static warning, o algo con un efecto similar.

+0

Terminé yendo con esta solución, envolviendo las afirmaciones con macros que no hacen nada con un cierto preprocesador. – Samaursa

0

Puede ejecutar su ejecutable a través de una herramienta de análisis estático después de la compilación siempre que haya configurado su compilador para incluir las tablas de símbolos adecuadas ... que mostrarán todas las clases creadas junto con sus argumentos de plantilla. Here is a link a una lista de herramientas que se pueden usar para el análisis de código estático.

2

Dado que está utilizando MSVC 2008, puede hacerlo generando un archivo de mapa de enlazador y buscando todas las instancias de esa función o inspeccionando el archivo .pdb a través de DIA. Deshabilitará el plegado de COMDAT con el indicador del enlazador/OPT: NOICF para que pueda encontrar las funciones que se compilan en el mismo ensamblaje.

Cuestiones relacionadas