2011-05-06 13 views
5

Considere ejemplo siguiente:La especialización de la función de plantilla después del punto de uso se romperá la compilación

#include <iostream> 

template< int a > 
void foo(); 

int main(int argn, char* argv[]) 
{ 
    foo<1>(); 
} 

template<> 
void foo<1>() 
{ 
    std::cout<<1<<std::endl; 
} 

La compilación falla con mensajes de error siguientes:

rg.cpp:12: error: specialization of ‘void foo() [with int a = 1]’ after instantiation 

Lo párrafo de la Norma se explica este error?

PD: Sé que si muevo la definición de función en frente de main, el error desaparecerá.

Respuesta

10

Creo que es comportamiento indefinido de acuerdo con la norma. No hay restricciones sobre lo que una cadena de herramientas puede hacer en casos de UB, generar un error de compilación es una de las posibilidades más amigables.


Sección [temp.spec], 14.7p5 dice

para una plantilla determinada y un conjunto dado de plantilla argumentos,

  • explícita de instancias de definición deberá aparecer como máximo una vez en un programa,
  • una especialización explícita se definirá como máximo una vez en un programa (según a 3.2) y
  • tanto una instanciación explícita como una declaración de especialización explícita no aparecerán en un programa a menos que la instanciación explícita siga a una declaración de especialización explícita.

No es necesaria una implementación para diagnosticar una infracción de esta regla.

Sección [temp.expl.spec] 14.7.3p6 dice:

Si una plantilla, una plantilla de miembro o un miembro de una plantilla de clase se especializa explícitamente a continuación que la especialización será declarado antes del primer uso de la especialización eso causaría que se produzca una instanciación implícita, en cada unidad de traducción en la que se produce dicho uso; no se requiere diagnóstico.


Su programa viole estos requisitos.

+0

+1 para la segunda cita. Estaba buscando eso. – Nawaz

+0

Sí, 14.7.3 es justo lo que estaba buscando. Gracias –

Cuestiones relacionadas