[ 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]
.