Ответ 1
[Примечание: Первоначально это не было вопросом для ответа на вопрос; Мне просто удалось найти ответ сам, пока я описывал свои попытки расследовать, и я подумал, что было бы неплохо поделиться им.]
В соответствии с Приложением C (2.14.5) стандарта С++ 11:
Тип строкового литерала изменяется от "array of char" до " массива const char." [....]
Кроме того, в пункте 7.1.6.2/4 указано (о результате decltype
):
Тип, обозначенный символом
decltype(e)
, определяется следующим образом:- если
e
является несвязанным id-выражением или несвязанным доступом к члену класса (5.2.5),decltype(e)
- это тип объекта с именемe
. Если такой объект отсутствует или еслиe
называет набор перегруженных функций, программа плохо сформирована;- в противном случае, если
e
является значением x,decltype(e)
являетсяT&&
, гдеT
является типомe
;- в противном случае, если
e
является lvalue,decltype(e)
являетсяT&
, гдеT
является типомe
;- в противном случае
decltype(e)
является типомe
.
Поскольку строковые литералы являются lvalues , согласно вышеприведенному абзацу и абзацу из приложения C, результат decltype("Hello")
является lvalue ссылается на массив размером 6 постоянных узких символов:
#include <type_traits>
int main()
{
// This will NOT fire
static_assert(
std::is_same<decltype("Hello"), char const (&)[6]>::value,
"Error!"
);
}
Наконец, хотя переменная hello
также является lvalue, второе утверждение времени компиляции из текста вопроса не срабатывает, потому что hello
- это unparenthesized id-expression, что заставляет его попадать в первый элемент вышеупомянутого перечня из пункта 7.1.6.2/4. Следовательно, результатом decltype(hello)
является тип объекта с именем hello
, который равен char const[6]
.