为什么对字符串字面值的decltype不产生数组类型

Why does decltype on a string literal not yield an array type?

本文关键字:数组 类型 decltype 字符串 字面值 为什么      更新时间:2023-10-16

标准在§2.13.5/8中定义了字符串文字的类型:

普通字符串字面值和UTF-8字符串字面值也被称为窄字符串字面值。窄字符串字面值的类型为" array of n const char ",其中n是下面定义的字符串的长度,并具有静态存储持续时间(3.7)。

因此,例如,"sss"应该具有类型char const[4](除非我读错了)。

但是这个简单的片段:

std::cout << std::boolalpha << std::is_pointer<decltype("sss")>::value << 'n';
std::cout << std::boolalpha << std::is_array<decltype("sss")>::value;

给:

false
false

我错过了什么?

字符串字面值为左值([expr.prim.general]/p1):

字面量是主表达式。它的类型取决于它的形式(2.13)。字符串字面值是左值;所有其他字面值都是左值。

当表达式expr为左值表达式([dcl.type.simple]/p4)时,

decltype(expr)返回左值引用:

对于表达式e,用decltype(e)表示的类型定义为:

  • 如果e是未加括号的id表达式或未加括号的类成员访问(5.2.5),则decltype(e)是实体的类型如果没有这样的实体,或者如果e命名了一组重载函数时,程序是病态的;
  • 否则,如果e是一个x值,则decltype(e)为T&&,其中T为e的类型;
  • 否则,如果e为左值,则decltype(e)为T&,其中T为e的类型;
  • 否则,decltype(e)为e的类型。

字符串字面值N const char数组,但是您正在经历的是decltype的效果。你真正拥有的是类型char const(&)[N],而不是 char const[N]

简单地删除引用应该会给你想要的行为:

std::is_array<std::remove_reference_t<decltype("sss")>>::value;

您必须首先删除引用,因为decltype推断的类型是const char (&)[N],而不仅仅是const char [N]:

std::cout << std::boolalpha << std::is_array<
    typename std::remove_reference<decltype("sss")>::type
>::value << 'n'; // true