Reputation: 610
I have a simple question: As I know I can declare a const
pointer to some datatype or a pointer to constant datatype but I can only declare a reference to a constant datatype only and no constant reference to a datatype; the fact that a reference is already constant because it cannot be rebound to another object.
So when I try to create a const ref to someDataType
I get compile-time error. But the thing that matters me is when used with type alias
using typedef
or using
. e.g:
#include <iostream>
int main() {
int i{ 10 };
// int& const r1{ i }; // error: ‘const’ qualifiers cannot be applied to ‘int&’. Ok here.
using rInt = int&; // or typedef int& rInt;
const rInt r2{ i }; // why const is allowed here?
++r2; // this proves that the const is applied to the reference not to the object referred to.
std::cout << r2 << std::endl; // 11
}
As you can see above I can add const
to the reference which I think is Redundant in that context. But why C++ allows this with type-aliases but not directly?
Upvotes: 9
Views: 1506
Reputation: 180845
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.
Upvotes: 5
Reputation: 238401
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.
Upvotes: 14