Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the rationale behind decltype behavior?

People also ask

What is decltype used for?

In the C++ programming language, decltype is a keyword used to query the type of an expression. Introduced in C++11, its primary intended use is in generic programming, where it is often difficult, or even impossible, to express types that depend on template parameters.

How does decltype work c++?

The decltype type specifier yields the type of a specified expression. 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 is the difference between auto and decltype Auto?

auto is a keyword in C++11 and later that is used for automatic type deduction. The decltype type specifier yields the type of a specified expression. Unlike auto that deduces types based on values being assigned to the variable, decltype deduces the type from an expression passed to it.


They wanted a way to get the type of declaration of an identifier.

They also wanted a way to get the type of an expression, including information about if it is a temporary or not.

decltype(x) gives the declared type of the identifier x. If you pass decltype something that is not an identifier, it determines the type, then appends & for lvalues, && for xvalues, and nothing for prvalues.

Conceptually you can think of it as the difference between the type of a variable and the type of an expression. But that is not quite how the standard describes it.

They could have used two different keywords to mean these two things. They did not.


There is some need for discriminating between an entity and an expression.

Consider the following question:

How long is Mississippi?

There are two answers to this question:

  1. Mississippi is 2,320 miles long.
  2. Mississippi is 11 letters long.

Similarly when you ask about the type of x, and x is an identifier, it is not clear whether you mean the type that was used to declare that identifier (i.e. the type associated with the name x), or the type of the expression consisting of the sole mentioning of that identifier. In fact there could be two different keywords (e.g. entity_type and expr_type) instead of a single overloaded decltype. For some reason, the committee chose to overload decltype for those two different uses.


From one of the authors of the decltype proposal, J. Jarvi:

It’s been a while, but here’s what I (think I) remember:

Two separate keywords for differentiating these two kinds of semantics was never considered. (Introducing new keywords is not done lightly).

As to the change of the semantics of decltype((x)), discussion in the core working group converged to treating (x) as an expression, rather than an identifier, which perhaps is more “internally consistent” with the language rules.

People were aware that this could potentially be confusing in some cases, but the consensus (while perhaps not everyone’s preference) was eventually to be consistent with the standard’s prior definition of what is an identifier and what is an expression.

The example you link to [this question's example] is indeed surprising. At the time, deducing a function’s return type from its return expression using decltype(auto) was not yet part of the language, so I don’t think this particular use case was on anyone’s radar.