There is no such thing as reference to a reference i.e. there is no T & &
.
Given a const T&
where T
is int&
, the type collapses into int&
.
What happens to const?
There is no such thing as a const reference either i.e. there is no T & const
(not to be confused with reference to const, which does exist and which is quite often colloquially called const reference). No reference can be modified (which would be different from modifying the referred object), so constness is not meaningful. The const is simply ignored here.
Standard rule (from latest draft):
[dcl.ref] If a typedef-name ([dcl.typedef], [temp.param]) or a decltype-specifier ([dcl.type.simple]) 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”, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.
[ Note: This rule is known as reference collapsing.
— end note
]
Here cv refers to cv-qualifiers i.e. const and volatile.
To clarify why this applies to template arguments:
[temp.param] A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name ...
P.S. The way reference collapsing is specified is part of the reason why perfect forwarding works.