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.
An array name contains the address of first element of the array which acts like constant pointer. It means, the address stored in array name can't be changed.
An array of references is illegal because a reference is not an object. According to the C++ standard, an object is a region of storage, and it is not specified if a reference needs storage (Standard §11.3.
Use references when you can, and pointers when you have to. References are usually preferred over pointers whenever you don't need “reseating”. This usually means that references are most useful in a class's public interface. References typically appear on the skin of an object, and pointers on the inside.
int*& ra = a;
int*
is a pointer type, not an array type. So that's why it won't bind to a
, which has type int[3]
.
int* const& ra = a;
works, because it is equivalent to
int* const& ra = (int*)a;
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:
int* ra = a;
where ra
is 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:
typedef int array_type[3];
array_type& ra = a;
The not-as-easy way:
int (&ra)[3] = a;
The C++11-easy way:
auto& ra = a;
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...
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);
, then pass_by_value(a)
will actually pass an int*
, because the array of type int[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 to int[3]
, but can bind to a temporary int*
, so the conversion happens.
The word "array" in C++ is spelled with brackets []
. If you want to declare a something-array-something in C++, you have to have brackets in your declaration. If you write an asterisk *
instead, you will get a pointer. Pointers and arrays are two different things.
This is a reference to an array:
int (&ra) [3] = a;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With