c++ - template - Cómo usar la plantilla externa
templates en c (1)
Dice
Excepto por ... especializaciones de plantillas de clase.
Por lo tanto, no se aplica a std::vector<int>
, sino a sus miembros (los miembros que no son funciones de miembro en línea y presumiblemente no son clases anidadas. Desafortunadamente, no hay un término que atrape a ambos) Especialización en plantillas de clase y especializaciones de clases miembro de plantillas de clase ". Por lo tanto, hay algunos lugares que usan solo el primero, pero también incluyen el segundo. Por lo tanto, std::vector<int>
y sus clases anidadas (como std::vector<int>::iterator
, si se define como una clase anidada) todavía se crearán instancias de forma implícita si es necesario.
He estado mirando a través del borrador de trabajo N3291 de C ++ 0x. Y tenía curiosidad por la plantilla externa. La sección 14.7.3 establece:
Con excepción de las funciones en línea y las especializaciones de plantillas de clase, las declaraciones de creación de instancias explícitas tienen el efecto de suprimir la creación de instancias implícita de la entidad a la que se refieren.
Para su información: el término "declaración de creación de instancias explícita" es estándar para la extern template
. Eso fue definido nuevamente en la sección 14.7.2.
Esto suena como si estuviera diciendo que si usa la extern template std::vector<int>
, entonces hacer cualquiera de las cosas que normalmente crearían una instancia implícitamente de std::vector<int>
no lo hará.
El siguiente párrafo es más interesante:
Si una entidad es el sujeto de una declaración de creación de instancias explícita y una definición de creación de instancias explícita en la misma unidad de traducción, la definición deberá seguir la declaración. Una entidad que sea el sujeto de una declaración de instanciación explícita y que también se use de una manera que de otra manera causaría una instanciación implícita (14.7.1) en la unidad de traducción será el sujeto de una definición de instanciación explícita en algún lugar del programa; De lo contrario, el programa está mal formado, no se requiere diagnóstico.
Para su información: el término "definición de creación de instancias explícita" es estándar habla de estas cosas: template std::vector<int>
. Es decir, sin el extern
.
Para mí, estas dos cosas dicen que la extern template
evita la creación de instancias implícita, pero no impide la creación de instancias explícita. Así que si haces esto:
extern template std::vector<int>;
template std::vector<int>;
La segunda línea niega efectivamente la primera haciendo explícitamente lo que la primera línea impidió que sucediera implícitamente.
El problema es este: Visual Studio 2008 no parece estar de acuerdo. La forma en que quiero usar la extern template
es evitar que los usuarios ejemplifiquen implícitamente ciertas plantillas de uso común, de modo que pueda crear instancias explícitas en los archivos .cpp para reducir el tiempo de compilación. Las plantillas solo serían instanciadas una vez.
El problema es que básicamente tengo que #ifdef alrededor de ellos en VS2008. Porque si una sola unidad de traducción ve la versión extern
y no extern
, hará que la versión extern
gane y nadie la ejemplificará. Y luego vienen los errores del enlazador.
Entonces, mis preguntas son:
- ¿Cuál es el comportamiento correcto según C ++ 0x? ¿Debería la
extern template
evitar la instanciación explícita o no? - Si la respuesta a la pregunta anterior es que no debería, entonces VS2008 está en error (concedido, fue escrito mucho antes de la especificación, por lo que no es su culpa). ¿Cómo maneja esto VS2010? ¿Implementa el comportamiento correcto de la
extern template
?