Каков результат decltype (& quot; Hello & quot;)?

Я получаю неожиданные результаты от всех компиляторов, на которых я пробовал следующее (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!");
}

Я бы ожидал утверждение времени компиляции выше не уволить, но это так. В конце концов, этот не (как ожидалось):

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

Так каков результат decltype("Hello") в соответствии со стандартом C ++ 11 (ссылки высоко ценятся)? С чем мне это сравнить, чтобы вышеупомянутое утверждение времени компиляции не сработало?

35

Решение

[Примечание. Изначально это не было вопросом с ответом; Я просто случайно нашел ответ, когда описывал свои попытки расследования, и я подумал, что было бы неплохо поделиться им.]

Согласно Приложению C (2.14.5) к стандарту C ++ 11:

Тип строкового литерала изменен с «array of char» на «массив константных символов.«[….]

Кроме того, пункт 7.1.6.2/4 уточняет (о результате decltype):

Тип обозначается decltype(e) определяется следующим образом:

— если e является не заключенным в скобки id-выражением или не заключенным в скобки доступом к классу (5.2.5), decltype(e) это тип объекта, названный e, Если такой организации нет, или если e называет набор перегруженных функций, программа некорректна;

— иначе, если e это xvalue, decltype(e) является T&&, где T это тип e;

в противном случае, если e это значение, decltype(e) является T&, где T это тип e;

— иначе, decltype(e) это тип e,

поскольку строковые литералы являются lvalues, в соответствии с вышеуказанным пунктом и пунктом из приложения С, результат 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 является не выраженное в скобках id-выражение, что делает его попадающим в первый пункт вышеприведенного списка из пункта 7.1.6.2/4. Следовательно, результат decltype(hello) это тип объекта, названный hello, который char const[6],

29

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]