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

前端 未结 2 489
無奈伤痛
無奈伤痛 2020-12-16 18:38

The standard defines a string literal\'s type, in §2.13.5/8, as:

Ordinary string literals and UTF-8 string literals are also referred to as narrow str

相关标签:
2条回答
  • 2020-12-16 18:47

    String literals are lvalues ([expr.prim.general]/p1):

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

    decltype(expr) returns an lvalue-reference when the expression expr is an lvalue expression ([dcl.type.simple]/p4):

    For an expression e, the type denoted by decltype(e) is defined as follows:

    • if e is an unparenthesized id-expression or an unparenthesized class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded func- tions, 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.

    String literals are arrays of N const char, but what you are experiencing is the effect of decltype. What you really have is the type char const(&)[N], not char const[N].

    Simply removing the reference should give you the behavior you desire:

    std::is_array<std::remove_reference_t<decltype("sss")>>::value;
    
    0 讨论(0)
  • 2020-12-16 19:06

    You have to remove the reference first, since the type deduced by decltype is const char (&)[N], not just const char [N]:

    std::cout << std::boolalpha << std::is_array<
        typename std::remove_reference<decltype("sss")>::type
    >::value << '\n'; // true
    
    0 讨论(0)
提交回复
热议问题