在声明对整数数组的引用时,为什么必须对常量指针进行引用? [英] When Declaring a Reference to an Array of Ints, why must it be a reference to a const-pointer?

查看:66
本文介绍了在声明对整数数组的引用时,为什么必须对常量指针进行引用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆