Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the behavior of decltype defined the way it is?

Tags:

c++11

decltype

From C++ Draft Standard N3337:

7.1.6.2 Simple type specifiers

4 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 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;

If I understand the above 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 that explains, why decltype(*ap) couldn't have been just int?

like image 571
R Sahu Avatar asked Sep 28 '14 19:09

R Sahu


People also ask

What is decltype used for?

The decltype type specifier, together with the auto keyword, is useful primarily to developers who write template libraries. Use auto and decltype to declare a template function whose return type depends on the types of its template arguments.

What does decltype stand for?

Decltype keyword in C++ Decltype stands for declared type of an entity or the type of an expression. It lets you extract the type from the variable so decltype is sort of an operator that evaluates the type of passed expression. SYNTAX : decltype( expression )

Is decltype evaluated at compile time?

decltype is a compile time evaluation (like sizeof ), and so can only use the static type.

What does decltype return?

decltype returnsIf what we pass to decltype is the name of a variable (e.g. decltype(x) above) or function or denotes a member of an object ( decltype x.i ), then the result is the type of whatever this refers to.


1 Answers

The standardization effort of decltype was a herculean effort spanning many years. There were 7 versions of this paper before the committee finally accepted it. The versions were:

  • N1478 2003-04-28
  • N1527 2003-09-21
  • N1607 2004-02-17
  • N1705 2004-09-12
  • N1978 2006-04-24
  • N2115 2006-11-05
  • N2343 2007-07-18

Remarkably, the seeds of the behavior which you question are in the very first revision: N1478, which introduces the need for "two types of typeof: either to preserve or to drop references in types."

This paper goes on to give a rationale for the reference-preserving variant, including this quote:

On the other hand, the reference-dropping semantics fails to provide a mechanism for exactly expressing the return types of generic functions, as demonstrated by Strous- trup [Str02]. This implies that a reference-dropping typeof would cause problems for writers of generic libraries.

There is no substitute for reading through these papers. However one might summarize that decltype serves two purposes:

  1. To report the declared type of an identifier.
  2. To report the type of an expression.

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

In your example, *ap is an expression, whereas a is an identifier. So your example makes use of both use cases, as first introduced in N1478.

It is also instructive to note that decltype was not designed in isolation. The rest of the C++ language was evolving during this time period (e.g. rvalue references), and the design of decltype was iterated to keep pace.

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

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

specifically section 7.1.6.2 (which is the section where the bulk of the decltype specification lives).

like image 140
Howard Hinnant Avatar answered Jan 02 '23 13:01

Howard Hinnant