2012-02-07 8 views
7

¿Por qué funciona esto?variable const como parámetro de plantilla sin tipo (VARIABLE no puede aparecer en una expresión constante)

char __nontype[] = "foo"; 
typedef TemplateClass<T, __nontype> MyClass; 

Pero esto (con una variable constante) no?

const char __nontype[] = "foo"; 
typedef TemplateClass<T, __nontype> MyClass; 

error del compilador:

error: '__nontype' no puede aparecer en una constante expresión

error: argumento de plantilla 2 no es válido

+2

Eso podría depender de la definición de TemplateClass <>. ¿Puedes publicar eso? – hatboyzero

+2

@hatboyzero no lo hace – sehe

+0

Creo que el malentendido fundamental aquí es que usted supone que el modificador 'const' automáticamente convierte algo en' constexpr'. Las matrices de Char no son constantes de tiempo de compilación; no se conocen hasta el tiempo del enlace. – tenfour

Respuesta

5

La diferencia se debe a que const afecta a la articulación. Funciona si agrega extern. Dicho esto, por lo que yo puedo decir:

14.3.2 Template non-type arguments [temp.arg.nontype]

A template-argument for a non-type, non-template template-parameter shall be one of:

  • an integral constant expression (including a constant expression of literal class type that can be used as an integral constant expression as described in 5.19); or
  • the name of a non-type template-parameter; or
  • a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or
  • a constant expression that evaluates to a null pointer value (4.10); or
  • a constant expression that evaluates to a null member pointer value (4.11); or
  • a pointer to member expressed as described in 5.3.1.

también debería funcionar sin extern. El objeto puede tener enlaces internos, pero su compilador aún no lo admite. Este es uno de los cambios en C++ 11, el estándar anterior de C++ no lo permitía.

+1

Ok, este parece ser el problema. ¡Buena respuesta! Por lo que he notado ahora, permitir enlaces internos es nuevo (c + + 11?). Pero, ¿por qué no estaba permitido? – ejoerns

+1

@ejoerns No sé si esta es la razón, pero solo el permitir objetos y funciones con enlaces externos hace que sea más fácil garantizar que todos los nombres destrozados de instancias de plantillas distintas difieran. – hvd

+1

@ejoerns Tienes razón en que es nuevo en C++ 11, por cierto. Acabo de verificar. – hvd

1

El error dice que: el resultado no es una expresión constante (se conoce en tiempo de enlace, pero no en tiempo de compilación).

Aquí es un ejemplo que haría trabajo:

typedef const char *nontype_t; 
template <nontype_t> struct Y {}; 

char hello[] = "hello"; 
constexpr char* world = hello; 

int main() 
{ 
    Y<hello> a; 
} 
+0

No lo entiendo ¿Cómo es el puntero a char más un puntero a objeto que puntero-a-const-char? – hvd

+1

Entonces, ¿por qué citó la parte del estándar que trata de qué tipos son aceptables? – hvd

+0

Puede ser un objeto con una duración de almacenamiento estático y, según el tipo de parámetro de la plantilla, sería válido. El problema es probable que el tipo del parámetro sea una matriz con tipo de carácter no const. –

Cuestiones relacionadas