I believe the code is valid and the two types are the same.
[dcl.ref]/1 says:
Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name (7.1.3, 14.1) or decltype-specifier (7.1.6.2), in which case the cv-qualifiers are ignored.
Since you are introducing the first const
through a decltype-specifier, it is ignored, and your first type is equivalent to decltype(b)&
.
Now [dcl.ref]/6 says:
If a typedef-name (7.1.3, 14.1) or a decltype-specifier (7.1.6.2) denotes a type TR
that is a reference to a type T
, an attempt to create the type "lvalue reference to cv TR
" creates the type "lvalue reference to T
" [...]
Your decltype-specifier denotes the type "reference to const int
", and you are attempting to create an lvalue reference, so you end up with an lvalue reference to const int
.