Reputation: 65
I'm very confused with decltype.
In the wiki(https://en.wikipedia.org/wiki/Decltype#Semantics), there is an example.
const int&& foo();
const int bar();
int i;
struct A { double x; };
const A* a = new A();
decltype(foo()) x1; // type is const int&&
decltype(bar()) x2; // type is int
decltype(i) x3; // type is int
decltype(a->x) x4; // type is double
decltype((a->x)) x5; // type is const double&
But, I don't understand at all about it.
decltype(bar()) x2; // type is int
I think type should be const int
because bar()
returns const int
and decltype(foo())
returns const int&&
. But, why is it just an int
?
decltype((a->x)) x5; // type is const double&
As wiki said,
The reason for the difference between the latter two invocations of decltype is that the parenthesized expression (a->x) is neither an id-expression nor a member access expression, and therefore does not denote a named object.[13] Because the expression is an lvalue, its deduced type is "reference to the type of the expression", or const double&
wiki said that the expression (a->x)
is an lvalue. But, AFAIK, lvalue is something that points to a specific memory location. Namely, it has its name or identifier. I think a->x
does got its name, but (a->x)
dosen't. Why it is a lvalue?
Upvotes: 1
Views: 140
Reputation: 1529
According to cppreference, we can classify that:
const int&& foo();
is an xvalue.const int bar();
is a prvalue.Searching for this brought me to this which states:
non-class prvalues always have cv-unqualified types
So its understood that return type of bar()
is an int
since its not a class type.
As to you second query:
Why it is a lvalue?
Because it has been mentioned in the standard as such. cppreference note:
Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression
You can think of (a->x)
as being the lhs of an assignment, and thus decltype((a->x))
returns a reference const int&
.
Upvotes: 1