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?
Respuesta
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.
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
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
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)
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.)
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.
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. –
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.
- 1. ¿Están el constructor y el destructor predeterminados siempre en línea?
- 2. Las plantillas de expresiones no están completamente delimitadas
- 3. ¿Dónde están todas las plantillas de correo electrónico de Magento?
- 4. ¿Cómo funcionan las funciones trigonométricas?
- 5. ¿Cómo funcionan los motores de plantillas en JavaScript?
- 6. ¿Cómo funcionan las cookies?
- 7. Cómo funcionan las sesiones en Codeigniter
- 8. ¿Las propiedades siempre tienen un valor cuando están desactivadas?
- 9. ¿Cómo funcionan las sesiones de PHP cuando las cookies están deshabilitadas?
- 10. ¿Cómo obtengo las plantillas en vivo de Scalaz IDEA que funcionan para los métodos simbólicos?
- 11. ¿Cómo se detiene el salto de línea automático después de las plantillas en mediawiki?
- 12. ¿Cómo funcionan las claves externas?
- 13. ¿Cómo funcionan las declaraciones preparadas?
- 14. Java: cómo funcionan las matrices
- 15. ¿Cómo funcionan las pasarelas API?
- 16. ¿Cómo funcionan las expresiones de consulta web2py?
- 17. ¿Funcionan las excepciones singleton?
- 18. ¿Cómo funcionan las actualizaciones en tiempo real?
- 19. ¿Cómo funcionan las banderas en C?
- 20. ¿Cómo funcionan las ecuaciones matemáticas en Java?
- 21. ¿Cómo funcionan los índices en las vistas?
- 22. ¿Cómo funcionan las excepciones en Haskell?
- 23. Apache ZooKeeper: cómo funcionan las escrituras
- 24. ¿Los constructores heredados funcionan con plantillas en C++ 0x?
- 25. ¿Simula objetos en C++ siempre requiere métodos o plantillas virtuales?
- 26. ¿Cómo desinstalar las plantillas de Cocos2d?
- 27. Un ternario en las plantillas
- 28. ¿Cuán profundo funcionan los compiladores en línea?
- 29. ¿Cómo funcionan las anotaciones de datos?
- 30. ¿Cómo se analizan las plantillas de django?
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