2011-11-12 6 views
6

Si intento compilar el siguiente código C++ 0x, me sale un error:error utilizando un constexpr como un parámetro de plantilla dentro de la misma clase

template<int n> struct foo { }; 

struct bar { 
    static constexpr int number() { return 256; } 

    void function(foo<number()> &); 
}; 

con GCC 4.6.1, el mensaje de error es :

test.cc:6:27: error: ‘static constexpr int bar::number()’ used before its definition 
test.cc:6:28: note: in template argument for type ‘int’ 

con sonido metálico 2.8, el mensaje de error es:

test.cc:6:20: error: non-type template argument of type 'int' is not an integral 
     constant expression 
     void function(foo<number()> &); 
          ^~~~~~~~ 
1 error generated. 

Si muevo la función constexpr a una base de c lass, funciona en gcc, y le da el mismo mensaje de error en sonido metálico:

template<int n> struct foo { }; 

struct base { 
    static constexpr int number() { return 256; } 
}; 

struct bar : base { 
    void function(foo<number()> &); 
}; 

es el código incorrecto, o se trata de una limitación o error en la aplicación de C++ 0x gcc 4.6? Si el código es incorrecto, ¿por qué está mal y qué cláusulas del estándar C++ 11 dicen que es incorrecto?

+2

Hmm .. Creo que acabamos de discutir esto antes: la definición de funciones en línea son tratados como si se definieron * * justo después de la definición de clase; por lo tanto, dentro de la definición de la clase todavía no están disponibles. Tenga en cuenta que siempre puede decir 'static const int number = 256;' o 'static constexpr int number = 256;' en su lugar. –

+0

@KerrekSB oh, nunca lo supe. Deberías escribir eso como una respuesta. –

+0

@KerrekSB: AFAIK, si uso 'static const int number = 256;', también necesito un 'const int bar :: number;', que agregaría inútilmente 4 bytes inútiles a '.data'. Usar una función en línea evita eso. No tengo idea si ese también es el caso para 'constexpr int number = 256;' estático, sin embargo. – CesarB

Respuesta

5

En C++, las definiciones en línea de las funciones miembro para una clase solo se analizan después de analizar cada declaración en la clase. Por lo tanto, en su primer ejemplo, el compilador no puede ver la definición de number() en el punto donde se declara function().

(No hay versión de lanzamiento de sonido metálico tiene soporte para la evaluación de las funciones constexpr, por lo que ninguno de sus casos de prueba funcionará allí.)

1

Tengo un error simillar con el siguiente código:

struct Test{ 
    struct Sub{constexpr Sub(int i){}}; 
    static constexpr Sub s=0; 
}; 

"error: 'constexpr Test :: Sub :: Sub (int)' llamado en una expresión constante" en gcc 4.7.1. Aunque esto va a compilar correctamente:

struct Sub{constexpr Sub(int i){}}; 
struct Test{ 
    static constexpr Sub s=0; 
}; 
+4

Por favor, solo brinde una respuesta si lo que está contribuyendo * responderá * a la pregunta que el usuario está presentando. Lo que ha publicado se considera más un comentario, que obtendrá el privilegio de publicar a medida que use más el sitio. Gracias por unirte a S.O. y bienvenido. – David

Cuestiones relacionadas