2011-03-25 6 views
6

Puedo entender cómo funciona si están alineados. Pero si no lo son, ¿cómo funciona? ¿todos los archivos objeto obtienen su propia copia de, por ejemplo, la plantilla de función de todos modos?¿Cómo funcionan las plantillas? ¿Están siempre en línea?

+0

Las plantillas son para generación de código. Si usa una plantilla, se genera y utiliza una clase/función. El compilador puede eliminar varias instancias de plantillas con los mismos parámetros, pero no está garantizado. No veo el enlace para enlining. – knivil

Respuesta

4

plantillas serán entre líneas en el sentido de la norma inline, que está más relacionado con la Regla de una sola definición que con el código real en línea. Es decir, el enlazador no se quejará si las funciones de la plantilla están definidas en más de una unidad de traducción, simplemente elegirá una (cuidado: una aleatoria, ¡los compiladores actuales no se quejan si proporciona diferentes definiciones de la plantilla en diferentes unidades de traducción!) y deja eso en el binario final.

Ahora, como con todas las demás funciones inline, el compilador puede decidir que es una buena idea evitar la llamada de función y alinear la función en el lugar de llamada, o podría determinar que no es tan buena. idea (gran función, algunos compiladores no incorporan funciones con bucles anidados ... cualquiera que sea el motivo) y luego no realizará el código real en línea.

+0

Y el compilador puede decidir "alinear" las funciones que no están declaradas 'en línea'. Me he dado cuenta de esto para funciones sin enlace externo, cuando se usa 'gcc'. – Raedwald

1

depende de la implementación.

Pero, por lo general, sí, cada archivo de objeto obtiene una copia de cada función expandida que utilizan. Y luego el enlazador nota esto en el tiempo del enlace y asegura que solo una copia de la función se pone en el archivo ejecutable final

2

Depende del compilador, pero cada uno que he visto crea una función que luego se puede llamar utilizando los parámetros de la plantilla sustituida para generar el código para cada variente.

como un (muy) ejemplo sencillo:

template <typename T> T Max(T a, T b) 
{ 
    return a > b ? a : b; 
} 

Cuando se invoca como Max<int> y Max<float> y no inline, el compilador genera (que están decoradas de una manera especial, sin embargo, para evitar otros problemas):

int Max(int a, int b) 
{ 
    return a > b ? a : b; 
} 

float Max(float a, float b) 
{ 
    return a > b ? a : b; 
} 

Esto entonces se ha quedado atascado en el inicio del objeto y luego se hace referencia, a continuación, se hace lo mismo para algunos inlines también (en MSVC)

2

Se depende Algunas de las implementaciones más populares hacen generan una copia del código de instanciación en cada archivo de objeto que desencadena una instanciación, y cuentan con el enlazador a descartar todos menos uno. Otros compiladores usan algún tipo de repositorio , donde se almacenan instancias; si la instanciación ya está presente, el compilador no molesta regenerandola. Esta solución es significativamente más rápida y usa menos disco que la primera solución, pero también es mucho más difícil obtener . (El compilador tiene que generar una nueva instanciación no sólo si uno no está presente, pero si alguno de los archivos de la instanciación depende han cambiado.)

0

plantillas son macros realmente muy, muy avanzadas (#define)

parámetros se reemplazan en tiempo de compilación con los valores pasados. Concepto realmente genial y también implementado muy bien.

+0

Las macros no deben mezclarse en el bote con plantillas y ya confundes sus conceptos: las macros se expanden directamente en el primer paso de traducción, es decir, pueden producir tokens que se deben pasar al analizador de C++. Esto no es posible con plantillas. –

0

Las plantillas son un lenguaje completo en sí mismas. Están completos, pero el "programa" se ejecuta en tiempo de compilación. Son fábricas de código que reemplazan el tipo de objeto en tiempo de compilación y ensamblan clases, funciones, etc. en tiempo de compilación.Así que puedes pensar que es un lenguaje de preprocesamiento masivo seguro y compatible con C++. La salida resultante de la ejecución es puro código C++ que luego puede ser tratado por el compilador de la misma manera que lo hace con todo lo demás.

Los compiladores generalmente ignoran en línea ya que muy pocos programadores pueden saber realmente cuándo es mejor y los que sí lo han hecho no han salido del ensamblado.

Cuestiones relacionadas