2011-11-22 8 views
5

tengo el siguiente código:Error de compilación de plantilla: estándar o no?

template<int k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    int k = 1000; 
    foo<k>(); 
    return 0; 
} 

cuales no se compila, pero si declaro como kconst, que hace:

template<int k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    const int k = 1000; 
    foo<k>(); 
    return 0; 
} 

Ahora, veo la lógica detrás de por qué en el primer caso no compila y en el segundo sí, ¿pero esto es especificado por el estándar?

El error que estoy recibiendo es:

Error 1 error C2971: 'foo' : template parameter 'k' : 'k' : a local variable cannot be used as a non-type argument 

que no es del todo claro, ya que k es una variable local también en el caso de que sea const ... ¿verdad?

Respuesta

2

§14.3.2.1 dice [abreviado]:

A template-argument for a non-type, non-template template-parameter shall be one of:
— an integral constant-expression of integral or enumeration type;

Y §5.19 0.1 dice [abreviado, el énfasis es mío]:

An integral constant-expression can involve only literals, enumerators, const variables or static data members of integral or enumeration types initialized with constant expressions...

Su segunda definición de k satisface esta, por lo que se le permite ser utilizado como un ICE para el argumento de plantilla.

El error es un poco confuso en el sentido de que "una variable local no se puede utilizar como un argumento sin tipo" es verdadero en general, pero con ciertas restricciones está perfectamente bien.

4

por la norma, 14.3.2, esto debe ser una expresión constante:

A template-argument for a non-type, non-template template-parameter shall be one of:
an integral constant-expression of integral or enumeration type; or
— the name of a non-type template-parameter; or
— the address of an object or function with external linkage, including function templates and function template-ids but excluding non-static class members, expressed as & id-expression where the & is optional if the name refers to a function or array, or if the corresponding template-parameter is a reference; or
— a pointer to member expressed as described in 5.3.1 .

GCC 4.6.2 da un error ligeramente más comprensible:

error: ‘k’ cannot appear in a constant-expression

+0

No especificó por qué 'k' funciona en uno pero no en el otro, que fue la base de la pregunta. – GManNickG

+0

Ver la sección en negrita. El estándar dice que la expresión debe ser constante. –

+0

Pero me repito a mí mismo: no abordas por qué 'k' es utilizable o no. – GManNickG

2

valores No. Const puede haber evaluado en el tiempo de compilación cuando el compilador intenta expandir las plantillas a la forma final. Así valores en tiempo de ejecución no pueden ser argumentos para las plantillas, pero siempre se puede ajustar la referencia de variable como parámetro de plantilla

template<int& k> 
void foo() 
{ 
} 
int main(int argc, char* argv[]) 
{ 
    int k = 1000; 
    foo<k>(); 
    return 0; 
} 
Cuestiones relacionadas