Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
300 views
in Technique[技术] by (71.8m points)

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

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 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 (3.7).

Therefore, for example, "sss" should have a type char const[4] (unless I'm reading it incorrectly).

But this simple snippet:

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

gives:

false
false

What am I missing?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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;

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.9k users

...