在声明对整数数组的引用时,为什么必须对常量指针进行引用? [英] When Declaring a Reference to an Array of Ints, why must it be a reference to a const-pointer?
问题描述
注意:我正在使用g ++编译器(听说它非常好,并且应该与标准非常接近).
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 };
现在让我们说您真的要声明对该数组的引用(不要介意为什么,除了Bjarne所说的语言支持它之外).
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).
案例1-如果您尝试:
int*& ra = a;
然后编译器不愿说:
"invalid initialization of non-const reference of type `int*&' from a temporary of type `int*'"
首先,为什么'a'是一个临时变量(即它在内存中没有位置?)...
First things first, why is 'a' a temporary variable (i.e. doesn't it have a place in memory?)...
无论如何,每当我看到非常量错误时,我都会尝试抛出const ...
Anyway, fine, whenever I see a non-const error, I try to throw in a const...
案例2-如果您尝试:
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.
案例3-现在这里将要编译的另一件事:
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.
所以这是我的问题:静态声明的数组的名称在什么时候出现?成为const指针?我似乎记得一个整数数组的名称也是一个指向int的指针,但是我不记得它曾经是一个const指向int的指针.
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...
案例1似乎失败了,因为声明(ra)的引用不是指向const指针的,这可能意味着'a'已经是一个从const指针到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.
案例2之所以有效,是因为声明的引用(rca)已经是一个const-pointer-to-int.
It seems like Case 2 works because the reference declared (rca) is already a const-pointer-to-int.
案例3也可以使用,这很简洁,但是为什么呢?假定的指向int的指针(即数组名称"a")在什么时候成为const指针?将其分配给int *(第1行)时会发生这种情况,还是将int *分配给int *&时会发生这种情况(第2行)?
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*& ra = a;
int *
是指针类型,而不是数组类型.这就是为什么它不会绑定到类型为 int [3]
的 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;
有效,因为它等效于
int* const& ra = (int*)a;
也就是说,概念上在赋值的右侧创建了一个临时的 pointer ,然后将该临时的绑定到 ra
上.所以最后,这并不比:
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;
其中 ra
实际上是指向数组第一个元素的指针,而不是对该数组的引用.
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;
不那么容易的方法:
int (&ra)[3] = a;
简单的C ++ 11方法:
The C++11-easy way:
auto& ra = a;
什么时候静态声明的数组的名称成为const-pointer?我似乎记得一个整数数组的名称也是一个指向int的指针,但是我不记得它曾经是一个const指向int的指针.
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:
- 尝试任何类型的复制"时都会发生衰变(因为C不允许直接复制数组)
- 衰变是一种转换,可以在允许转换的任何时候发生:当类型不匹配时
第一类通常发生在模板上.因此,给定 template< typename T>pass_by_value(T);
,那么 pass_by_value(a)
实际上会传递 int *
,因为类型为 int [3]
无法复制.
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.
对于第二个,您已经看到了它的作用:在您的第二种情况下,当 int * const&
无法绑定到 int [3]
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.
这篇关于在声明对整数数组的引用时,为什么必须对常量指针进行引用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!