Why I can declare a const reference using type-alias?
Because the standard say so:
[dcl.ref] ... Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.simple]), in which case the cv-qualifiers are ignored
This is similar to how you cannot declare a reference reference, while it is possible through a typedef (where the references collapse into one):
int i;
int& iref = i;
//int& & irefref = iref; // not OK
using Iref = int&;
Iref& iretypedef = iref; // OK; collapses into int&
The CV-collapsing rules, just like reference collapsing rules are essential to make templates and type deductions usable.
This is a case where common sense comes into play. Since references cannot be reassigned they act as if they were const
. Adding const
to a reference declaration doesn't add anything and as such T & const
is forbidder per [dcl.ref]/1
[...] Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef-name ([dcl.typedef], [temp.param]) or decltype-specifier ([dcl.type.simple]), in which case the cv-qualifiers are ignored.
You'll notice though that it is allowed then the reference is a typedef-name or decltype-specifier. So if T
is T&
then the const
is ignored. If it wasn't it would make generic programming harder.