c++ - name - ¿Tiene algún sentido usar palabra clave en línea con plantillas?
meta title seo (3)
Como sugirió, en inline
es una pista para el compilador y nada más. Puede elegir ignorarlo o, de hecho, las funciones en línea no marcadas en línea.
Usar en inline
con las plantillas solía ser una forma (deficiente) de evitar el problema de que cada unidad de compilación crearía un objeto separado para la misma clase de plantilla que causaría problemas de duplicación en el momento del enlace. Al usar en inline
(creo), el cambio de nombre funciona de forma diferente, lo que hace que el nombre se desvanezque en el tiempo del enlace, pero a expensas de un código muy inflado.
Marshall Cline lo explica aquí mejor que yo.
Dado que las plantillas se definen dentro de los encabezados y el compilador puede determinar si la inclusión de una función es ventajosa, ¿tiene algún sentido? He oído que los compiladores modernos saben mejor cuándo alinear una función y están ignorando la pista en inline
.
editar: me gustaría aceptar ambas respuestas, pero esto no es posible. Para cerrar el tema, estoy aceptando la respuesta de phresnel , porque recibió la mayoría de los votos y formalmente tiene razón, pero como mencioné en los comentarios, considero que las respuestas de Puppy y Component 10 también son correctas, desde diferentes puntos de vista. .
El problema está en la semántica de C ++, que no es estricta en el caso de la palabra clave en inline
y en inline
. phrenel dice "escriba en línea si lo dice en serio", pero lo que significa en realidad no está claro, ya que evolucionó de su significado original a una directiva que "detiene a los compiladores quejándose de las violaciones a la ODR", dice Puppy .
Es irrelevante Todas las plantillas ya están en inline
, sin mencionar que a partir de 2012, el único uso de la palabra clave en inline
es detener a los compiladores quejándose de las violaciones a la ODR. Tiene toda la razón: el compilador de la generación actual sabrá qué hacer por sí mismo y probablemente lo haga incluso entre unidades de traducción.
No es irrelevante. Y no, no todas las plantillas de funciones están en inline
por defecto. El estándar es incluso explícito al respecto en especialización explícita ([temp.expl.spec])
Tiene lo siguiente:
a.cc
#include "tpl.h"
b.cc
#include "tpl.h"
tpl.h (tomado de la especialización explícita):
#ifndef TPL_H
#define TPL_H
template<class T> void f(T) {}
template<class T> inline T g(T) {}
template<> inline void f<>(int) {} // OK: inline
template<> int g<>(int) {} // error: not inline
#endif
Compila esto, et voila:
g++ a.cc b.cc
/tmp/ccfWLeDX.o: In function `int g<int>(int)'':
inlinexx2.cc:(.text+0x0): multiple definition of `int g<int>(int)''
/tmp/ccUa4K20.o:inlinexx.cc:(.text+0x0): first defined here
collect2: ld returned 1 exit status
No declarar en inline
cuando se realiza una instanciación explícita también puede generar problemas.
Por lo tanto, en resumen : para las plantillas de funciones no totalmente especializadas, es decir, aquellas que llevan al menos un tipo desconocido, puede omitir en inline
, y no recibir errores, pero todavía no están en inline
. Para especializaciones completas, es decir, aquellas que usan solo tipos conocidos, no puede omitirlo.
Regla de oro propuesta : escriba en inline
si lo dice en serio y sea consistente. Te hace pensar menos sobre si debes o no hacerlo solo porque puedes. (Esta regla de oro se ajusta a Vandevoorde / Josuttis''s C ++ Template: The Complete Guide ).