auto
and decltype
Explained,
by Thomas Becker
about me
decltype
Deduces the Type of an Expression: Case 1
The way decltype goes about determining the type of an expression is different
from what auto does.
It is based on a case distinction. There are two cases. The first case is when the expression
whose type is to be determined is a plain variable or function parameter, like x , or a class member
access, like p->m_x . In that case, decltype lives up to its name: it determines the type of the expression
to be the declared type, that is, the type that we find in the source code at the point
of declaration. When I say "find in the source code," that may of course
involve going through some levels of indirection, like resolving typedefs or performing template
instantiations. But apart from that, we are talking about a situation where the type of the
epxression is lexically present in the source code.
|
If expr is a is a plain, unparenthesized variable, function parameter, or class member
access, then decltype(expr) is the type of that variable, function parameter,
or class member as declared in the source code.
|
Here are some concrete examples. For each example, we also indicate
what auto would do (decltype is blue,
auto is green).
struct S { S(){m_x = 42;} int m_x; }; int x; const int cx = 42; const int& crx = x; const S* p = new S(); // x is declared as an int: x_type is int. // typedef decltype(x) x_type; // auto also deduces the type as int: a is an int. // auto a = x; // cx is declared as const int: cx_type is const int. // typedef decltype(cx) cx_type; // auto drops the const qualifier: b is int. // auto b = cx; // crx is declared as const int&: crx_type is const int&. // typedef decltype(crx) crx_type; // auto drops the reference and the const qualifier: c is an int. // auto c = crx; // S::m_x is declared as int: m_x_type is int // // Note that p->m_x cannot be assigned to. It is effectively // constant because p is a pointer to const. But decltype goes // by the declared type, which is int. // typedef decltype(p->m_x) m_x_type; // auto sees that p->m_x is const, but it drops the const // qualifier. Therefore, d is an int. // auto d = p->m_x; |