36 votes

Quel est le résultat de decltype("Hello") ?

J'obtiens des résultats inattendus de tous les compilateurs sur lesquels j'ai essayé les éléments suivants (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!"
        );
}

Je me serais attendu à ce que l'assertion de compilation ci-dessus pas pour tirer, mais ça marche. Après tout, celui-ci ne le fait pas (comme prévu) :

#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!"
        );
}

Alors quel est le résultat de decltype("Hello") selon la norme C++11 (les références sont très appréciées) ? À quoi dois-je le comparer pour que l'assertion de compilation ci-dessus ne se déclenche pas ?

30voto

Andy Prowl Points 62121

[ Remarque : à l'origine, il ne s'agissait pas d'une question à laquelle j'ai répondu moi-même ; j'ai trouvé la réponse par hasard en décrivant mes tentatives d'investigation, et j'ai pensé qu'il aurait été bon de la partager. ]

Selon l'annexe C (2.14.5) de la norme C++11 :

Le type d'un littéral de chaîne passe de "array of char" à "array of char". tableau de const chars ." [....]

En outre, le paragraphe 7.1.6.2/4 précise (au sujet du résultat de decltype ) :

Le type désigné par decltype(e) est défini comme suit :

- si e est une expression d'identification non parenthésée ou un accès à un membre de classe non parenthésé (5.2.5), decltype(e) est le type de l'entité nommée par e . Si une telle entité n'existe pas, ou si e nomme un ensemble de fonctions surchargées, le programme est mal formé ;

- sinon, si e est une valeur x, decltype(e) es T&& , donde T est le type de e ;

- sinon, si e est une lvalue, decltype(e) es T& , donde T est le type de e ;

- autrement, decltype(e) est le type de e .

Depuis les littéraux de chaîne sont des valeurs l Selon le paragraphe ci-dessus et le paragraphe de l'annexe C, le résultat de l'évaluation de l'impact sur l'environnement est le suivant decltype("Hello") est un référence à la valeur lval de un tableau de taille 6 de caractères étroits constants :

#include <type_traits>

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

Enfin, même si le hello variable est est aussi une lvalue, la deuxième assertion de compilation du texte de la question ne se déclenche pas, car hello est un expression d'identité non parenthésée ce qui le fait tomber dans le premier élément de la liste ci-dessus du paragraphe 7.1.6.2/4. Par conséquent, le résultat de decltype(hello) est le type de l'entité nommée par hello qui est char const[6] .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X