If you read e.g. this decltype
reference you will see
2) If the argument is an unparenthesized id-expression or an unparenthesized class member access expression, ...
3) If the argument is any other expression...
...
b) if the value category of expression is lvalue, then decltype
yields T&
;
[Emphasis mine]
And then a little further down the note
Note that if the name of an object is parenthesized, it is treated as an ordinary lvalue expression, thus decltype(x)
and decltype((x))
are often different types.
Because you use a parenthesized expression it is treated as an lvalue, meaning that 3.b above is active and decltype((x))
gives you int&
if x
is int
.
It should be noted that while the reference isn't authoritative it is derived from the specification and generally reliable and correct.
From the C++11 specification ISO/IEC 14882:2011, section 7.1.6.2 [dcl.type.simple], sub-section 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
;
— otherwise, decltype(e)
is the type of e
And with an example:
struct A { double x; };
const A* a = new A();
...
decltype((a->x)) x4 = x3; // type is const double&
Basically exactly what the previously linked reference said.
With your example, e
in the specification is (x)
(since you have declspec((x))
). Now the first case doesn't fit because (x)
is not an unparenthesized expression. The second case doesn't fit because (x)
isn't an xvalue. The third case matches though, (x)
is an lvalue of type int
, leading decltype((x))
to be int&
.
So the answer to your query is simply: Because the specification says so.