#include <iostream>
struct Test{
Test(int& r):rf(r){
}
int& rf;
};
int main(){
int a = 0;
Test t(a);
decltype(t.rf) b;
}
Consider the above code, the compiler complains such a code is ill-formed, because b is of reference type and it's not be initialized. However according to the following rules, I wonder why the type of b is a reference type?
dcl.type.simple#4
For an expression e, the type denoted by decltype(e) is defined as follows:
- if e is an unparenthesized id-expression naming a structured binding ([dcl.struct.bind]), decltype(e) is the referenced type as given in the specification of the structured binding declaration;
- otherwise, if e is an unparenthesized id-expression or an unparenthesized class member access, 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;
And according to what the paragraph expr.ref#4 says:
If E2 is declared to have type “reference to T”, then E1.E2 is an lvalue; the type of E1.E2 is T. Otherwise, one of the following rules applies.
It means that the type of t.rf is int. I have to say it is vague that the section [expr.ref] does not say, E1.E2 is still a reference(what is the exactly entity the expression E1.E2 denotes?). It just say such an expression is lvalue and its type is what the reference refer to.
I only find a special rule in [expr], that is:
expr#5
If an expression initially has the type “reference to T” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression. [ Note: Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see [basic.life]). — end note ]
Does it mean that before analyzing the expression t.rf, since rf has the type “reference to T”, it should be adjusted to int and such an expression, namely rf designates a to which it refers.
So, According to these above rules, the result of decltype(t.rf) should be int, why the compiler consider it as int&?