This may seem counter-intuitive but I think the way to understand this is to realize that, in certain respects, references are treated syntactically like pointers.
This seems logical for a pointer:
int main()
{
boolalpha(cout);
int const i = 1;
cout << is_const<decltype(i)>::value << endl;
int const* ri = &i;
cout << is_const<decltype(ri)>::value << endl;
}
Output:
true
false
This is logical because we know it is not the pointer object that is const (it can be made to point elsewhere) it is the object that is being pointed to.
So we correctly see the constness of the pointer itself returned as false
.
If we want to make the pointer itself const
we have to say:
int main()
{
boolalpha(cout);
int const i = 1;
cout << is_const<decltype(i)>::value << endl;
int const* const ri = &i;
cout << is_const<decltype(ri)>::value << endl;
}
Output:
true
true
And so I think we see a syntactic analogy with the reference.
However references are semantically different to pointers especially in one crucial respect, we are not allowed to rebind a reference to another object once bound.
So even though references share the same syntax as pointers the rules are different and so the language prevents us from declaring the reference itself const
like this:
int main()
{
boolalpha(cout);
int const i = 1;
cout << is_const<decltype(i)>::value << endl;
int const& const ri = i; // COMPILE TIME ERROR!
cout << is_const<decltype(ri)>::value << endl;
}
I assume we are not allowed to do this because it doesn’t appear to be needed when the language rules prevent the reference from being rebound in the same way a pointer could(if it is not declared const
).
So to answer the question:
Q) Why “reference” is not a “const” in C++?
In your example the syntax makes the thing being referred to const
the same way it would if you were declaring a pointer.
Rightly or wrongly we are not allowed to make the reference itself const
but if we were it would look like this:
int const& const ri = i; // not allowed
Q) we know once a reference is bind to a name/variable, we cannot change this binding, we change its binded object.
So I suppose the type ofri
should be same asi
: wheni
is aint const
, whyri
is notconst
?
Why is the decltype()
not transferred to the object the referece is bound to?
I suppose this is for semantic equivalence with pointers and maybe also the function of decltype()
(declared type) is to look back at what was declared before the binding took place.