Note: I am using the g++ compiler (which is I hear is pretty good and supposed to be pretty close to the standard).
Let’s say you have declared an array of ints:
int a[3] = { 4, 5, 6 };
Now let’s say you really want to declare a reference to that array (nevermind why, other than the Bjarne says the language supports it).
Case 1 — If you try:
int*& ra = a;
then the compiler balks and says:
"invalid initialization of non-const reference of type `int*&' from a temporary of type `int*'"
First things first, why is ‘a’ a temporary variable (i.e. doesn’t it have a place in memory?)…
Anyway, fine, whenever I see a non-const error, I try to throw in a const…
Case 2 — if you try:
int*const&rca = a; //wish I knew where the spaces should go (but my other post asking about this sort of protocol got a negative rank while many of the answers got ranked highly -- aha! there are stupid questions!)
Then everything is cool, it compiles, and you get a reference to the array.
Case 3 — Now here is another thing that will compile:
int* justSomeIntPointer = a; //LINE 1
int*& rpa = justSomeIntPointer; //LINE 2
This also gives you a reference to the original array.
So here is my question: At what point does the name of a statically declared array
become a const-pointer? I seem to remember that the name of an array of ints is also a pointer-to-int, but I don’t remember it ever being a const-pointer-to-int…
It seems like Case 1 fails because the reference declared (ra) is not to a const-pointer, which may mean that ‘a’ was already a const-pointer-to-int to begin with.
It seems like Case 2 works because the reference declared (rca) is already a const-pointer-to-int.
Case 3 also works, which is neat, but why? At what point does the assumed pointer-to-int (i.e. the array name ‘a’) become a const-pointer? Does it happen when you assign it to an int* (LINE 1), or does it happen when you assign that int* to a int*& (LINE 2)?
Hope this makes sense. Thanks.
int*is a pointer type, not an array type. So that’s why it won’t bind toa, which has typeint[3].works, because it is equivalent to
That is, a temporary pointer is conceptually created on the right-hand side of the assignment and this temporary is then bound to
ra. So in the end, this is no better than:where
rais in fact a pointer to the first element of the array, not a reference to the array.Declaring a reference to an array the easy way:
The not-as-easy way:
The C++11-easy way:
This is the right question to ask! If you understand when array-to-pointer decay happens, then you’re safe. Simply put there are two things to consider:
The first kind typically happen with templates. So given
template<typename T> pass_by_value(T);, thenpass_by_value(a)will actually pass anint*, because the array of typeint[3]can’t be copied in.As for the second one, you’ve already seen it in action: this happens in your second case when
int* const&can’t bind toint[3], but can bind to a temporaryint*, so the conversion happens.