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


Estoy obteniendo resultados inesperados de todos los compiladores en los que probé 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!"
        );
}

Habría esperado que la afirmación de tiempo de compilación anterior no se disparara, pero lo hace. Después de todo, este no lo hace (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") según el estándar C++11 (las referencias son muy apreciadas)? ¿Con qué debería compararlo para que la afirmación de tiempo de compilación anterior no ¿fuego?

Author: Andy Prowl, 2013-02-24

1 answers

[Nota: Originalmente, esto no estaba destinado a ser una pregunta auto-respondida; simplemente encontré la respuesta yo mismo mientras describía mis intentos de investigar, y pensé que habría sido bueno compartirla.]

De acuerdo con el anexo C (2.14.5) del estándar 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 (acerca de el resultado de decltype):

El tipo indicado por decltype(e) se define como sigue:

- si e es una expresión id sin resolver o un acceso miembro de clase sin resolver (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 xvalue, decltype(e) es T&&, donde T es el tipo de e;

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

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

Desde los literales de cadena son lvalues, según el párrafo anterior y el Párrafo del Anexo C, el resultado de decltype("Hello") es un lvalue referencia 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 es también un lvalue, la segunda aserción en tiempo de compilación del texto de la pregunta no se dispara, porque hello es una expresión id sin compilar, lo que la hace caer 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 la entidad nombrada por hello, que es char const[6].

 29
Author: Andy Prowl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:32:01