c++ c++11 string-literals decltype

c++ - ¿Cuál es el resultado de decltype("Hola")?



c++11 string-literals (1)

Obtengo resultados inesperados de todos los compiladores en los que intenté lo siguiente (GCC 4.7.2, GCC 4.8.0 beta, ICC 13.0.1, Clang 3.2, VC10):

#include <type_traits> int main() { // This will fire static_assert( std::is_same<decltype("Hello"), char const[6]>::value, "Error!" ); }

Hubiera esperado que la afirmación en tiempo de compilación anterior no se activara, pero lo hace. Después de todo, este no (como se esperaba):

#include <type_traits> int main() { char const hello[6] = "Hello"; // This will not fire static_assert( std::is_same<decltype(hello), char const[6]>::value, "Error!" ); }

Entonces, ¿cuál es el resultado de decltype("Hello") acuerdo con el estándar C ++ 11 (las referencias son muy apreciadas)? ¿Con qué debería compararlo para que no se active la afirmación en tiempo de compilación anterior?


[ Nota: Originalmente, esto no tenía la intención de ser una pregunta auto-respondida; Solo encontré la respuesta yo mismo mientras describía mis intentos de investigar, y pensé que habría sido agradable compartirla. ]

De acuerdo con el Anexo C (2.14.5) de la Norma C ++ 11:

El tipo de un literal de cadena se cambia de "array of char" a " array of const char ". [....]

Además, el Párrafo 7.1.6.2/4 especifica (sobre el resultado de decltype ):

El tipo indicado por decltype(e) se define de la siguiente manera:

- si e es una expresión de id no aparente o un acceso de miembro de clase no apareado (5.2.5), decltype(e) es el tipo de la entidad nombrada por e . Si no existe tal entidad, o si e nombra un conjunto de funciones sobrecargadas, el programa está mal formado;

- de lo contrario, si e es un valor decltype(e) , decltype(e) es T&& , donde T es el tipo de e ;

- de lo contrario, si e es un valor decltype(e) , decltype(e) es T& , donde T es el tipo de e ;

- De lo contrario, decltype(e) es el tipo de e .

Como los literales de cadena son lvalues , de acuerdo con el párrafo anterior y el párrafo del anexo C, el resultado de decltype("Hello") es una referencia lvalue a una matriz de tamaño 6 de caracteres estrechos constantes:

#include <type_traits> int main() { // This will NOT fire static_assert( std::is_same<decltype("Hello"), char const (&)[6]>::value, "Error!" ); }

Finalmente, aunque la variable hello también es un lvalue, la segunda aserción en tiempo de compilación del texto de la pregunta no se activa , porque hello es una expresión id no aparente , lo que hace que caiga en el primer elemento de la lista anterior del Párrafo 7.1 .6.2 / 4. Por lo tanto, el resultado de decltype(hello) es el tipo de entidad llamada por hello , que es char const[6] .