Why is decltype behavior defined as it is?

From C ++ Draft Standard N3337:

7.1.6.2 Simple Type Qualifiers

4 The type indicated by decltype(e) is defined as follows:

- if e is a non-spherical id expression or unrelated access to a class member (5.2.5), decltype(e) is a type of object called e . If such an object is absent or if e calls a set of overloaded functions, the program is poorly formed;

- otherwise, if e is a value of x, decltype(e) is T&& , where T is a type of e ;

- otherwise, if e is an lvalue, decltype(e) is T& , where T is a type of e ;

If I understood this correctly,

 int a; decltype(a) b = 10; // type of b is int int* ap; decltype(*ap) c = 10; // Does not work since type of c is int& 

Can you explain or point to some documentation explaining why decltype(*ap) could not be just int ?

+5
source share
1 answer

The decltype standardization decltype is a tragedy spanning many years. There were 7 versions of this article before the committee finally adopted it. Versions were:

It is noteworthy that the seeds of behavior of which you doubt are in the first edition: N1478 , which introduces the need for "two typesof typeof: either save or reset links in types."

This article provides the rationale for saving links, including this quote:

On the other hand, the semantics of dropping links does not provide a mechanism for expressing exactly the return types of common functions, as demonstrated by Stroustrup [Str02]. This means that a reference type can cause problems for authors of shared libraries.

There is no substitute for reading these documents. However, we can say that decltype serves two purposes:

  • To report a declared identifier type.
  • To tell the type of expression.

For the second use case, remember that expressions are never reference types, but instead are one of lvalues, xvalues, or prvalues. By convention, when decltype reports the type of an lvalue expression, it makes the type a lvalue reference, and when the expression is an x ​​value, the reported type becomes an rvalue reference.

In your example, *ap is an expression, while a is an identifier. Thus, your example uses both use cases, as first introduced in N1478 .

It should also be noted that decltype not developed in isolation. The rest of the C ++ language evolved during this period of time (for example, references to rvalue), and the decltype design decltype repeated to keep up.

Also note that once the decltype proposal decltype been accepted, it continued (and continues to this day) to evolve. See the list of questions:

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_index.html

in particular section 7.1.6.2 (which is the section that contains the bulk of the decltype specification).

+6
source

Source: https://habr.com/ru/post/1203566/


All Articles