Я получаю неожиданные результаты от всех компиляторов, на которых я пробовал следующее (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 (ссылки высоко ценятся)? С чем мне это сравнить, чтобы вышеупомянутое утверждение времени компиляции не сработало?
Согласно Приложению 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]
,
Других решений пока нет …