FANG
  • 131

C++11 的 is_array 函数无法判断字符串字面量

int main()
{
    std::cout << typeid("asd").name() << '\n';
    std::cout << std::is_array_v<decltype("asd")> << '\n';
    std::cout << std::is_pointer_v<decltype("asd")> << '\n';
}

在 Visual Studio 2019 输出:

char const [4]
0
0

GCC 也是一样。字符串字面量难道既不是数组也不是指针?

阅读 219
评论 3月26日提问
    2 个回答
    fefe
    • 7.6k

    decl.type.simple/4:

    For an expressione, the type denoted bydecltype(e)is defined as follows:

    • if e is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(e) is the referenced type as given in the specification of the structured binding declaration;
    • otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, decltype(e) is the type of the entity named bye. If there is no such entity, or ifenames a set of overloaded functions, the program is ill-formed;
    • otherwise, if e is an xvalue, decltype(e) is T&&, where T is the type of e;
    • otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
    • otherwise, decltype(e) is the type of e.

    expr.prim.literal/1

    A literal s a primary expression. Its type depends on its form. A string literal is an lvalue; all other literals are prvalues.

    lex.string/8

    Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char, where n is the size of the string as defined below, and has static storage duration.

    只有对 id-expression 以及 prvalue ,decltype(e) 才会直接返回 e 的类型。

    否则,对 xvalue 返回 T&& ,对 lvalue 返回 T&。

    "abs" 的类型是 const char[4],lvalue
    它既不是 id-expression 也不是 xvalue,所以 decltype("abc") 会得到 const char(&)[4]

    评论 赞赏 3月26日
      FANG
      • 131

      更新:

      decltype("asd") 得到的类型其实是 const char (&)[4],故

      int main()
      {
          std::cout << typeid("asd").name() << '\n';
          std::cout << std::is_array_v<std::remove_reference_t<decltype("asd")>> << '\n';
          std::cout << std::is_pointer_v<std::remove_reference_t<decltype("asd")>> << '\n';
      }

      输出

      char const [4]
      1
      0
      评论 赞赏 3月26日
        撰写回答

        登录后参与交流、获取后续更新提醒