The reference is dropped when evaluating the type of the expression (as per § 5/5), but this does not change the fact that the function call expression f()
is an lvalue. Per paragraph 5.2.2/10 of the C++11 Standard:
A function call is an lvalue if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise.
In other words, the reference is not dropped from the return type of the function itself, only from the type of the evaluated function call expression (which is, therefore, int
).
The fact that the function is returning an lvalue reference is what allows the type system to classify corresponding function call expressions as lvalues - which, in turn, allows decltype
to add the lvalue reference to the type of the expression, thus yielding int&
.