C++ 当对数组使用auto时,为什么它';是否转换为指针而不是引用?
请参见以下示例:C++ 当对数组使用auto时,为什么它';是否转换为指针而不是引用?,c++,arrays,c++11,language-design,C++,Arrays,C++11,Language Design,请参见以下示例: int arr[10]; int *p = arr; // 1st valid choice int (&r)[10] = arr; // 2nd valid choice 现在,当我们对arr使用auto时,它选择第一个选项 auto x = arr; // x is equivalent to *p 是否有使用数组的原因?自动生成值。它不会产生引用。记住这一点,那么指针就是对数组提供的值的简单转换。是。在该表达式中,由于从左值到右值的转换,数组将衰减为指针类型
int arr[10];
int *p = arr; // 1st valid choice
int (&r)[10] = arr; // 2nd valid choice
现在,当我们对arr
使用auto
时,它选择第一个选项
auto x = arr; // x is equivalent to *p
是否有使用数组的原因?自动生成值。它不会产生引用。记住这一点,那么指针就是对数组提供的值的简单转换。是。在该表达式中,由于
从左值到右值的转换,数组将衰减为指针类型
如果需要数组类型而不是指针类型,请执行以下操作:
auto & x = arr; //now it doesn't decay into pointer type!
目标类型中的&
可防止数组退化为指针类型
x
是一个数组而不是指针,可以证明为:
void f(int (&a)[10])
{
std::cout << "f() is called. that means, x is an array!" << std::endl;
}
int main() {
int arr[10];
auto & x = arr;
f(x); //okay iff x is an int array of size 10, else compilation error!
}
ideone演示:
请注意,不能使用指针类型调用f
。可以使用大小为10
的int
数组调用它。试图用任何其他类型调用它将导致编译错误。对于数组arr
,表达式arr
本身意味着&arr[0]
。该规则来自C。因此,IMO自动选择指针。为提供行为的标准参考,7.1.6.4[dcl.spec.auto]第6段如下:
根据8.3确定声明器id的类型后,使用声明器id的声明变量的类型将使用模板参数推断规则从其初始值设定项的类型确定。设T为已为变量标识符d确定的类型。通过将出现的自动替换为。。。提出了一种新型模板参数U。。。然后,根据函数调用(14.8.2.1)中的模板参数推导规则确定变量d的推导类型A,其中P是函数模板参数类型,d的初始值设定项是相应的参数。如果扣除失败,则声明格式错误
因此,我们需要看看其他地方,特别是14.8.2.1[tmp.扣除.调用]第2段:
如果p不是引用类型:-如果a是数组类型,则使用数组到指针标准转换(4.2)生成的指针类型代替a进行类型推断
为完整起见,第4.2节[conv.array]第1段:
“NT数组”或“T未知界数组”类型的左值或右值可以转换为“指向T的指针”类型的PR值。结果是指向数组第一个元素的指针
要单步通过它,auto x=arr代码>创建一个虚函数模板f(P)
并尝试从调用f(arr)
推断P
<在本例中,code>A
是10 int的数组,而P
不是引用类型,因此A
变为指向int的指针。它向上渗透到链的最后一种x
因此,基本上,它被视为指针,因为规则规定它必须。因为数组是不可赋值的,所以这种行为更有用。否则,您的auto x=arr
将无法编译,而无法执行有用的操作。您能解释一下您所说的自动生成值是什么意思吗?@Space\u C0wb0y:我的理解是,例如int y=0;自动x=y
不会产生对int的引用。事实上,事实证明,auto
本身并不能定义引用,这就是auto&
的用途。作为数组的RHS也不例外-auto
本身并不定义引用,而是定义对象int*
和const int*
是表达式arr
是有效初始值设定项的唯一对象类型,因此显然x
必须具有typeint*
,这是表达式arr
的类型作为右值。请注意,如果数组是可复制/可分配的,那么我们在这里会有歧义,也许auto x=arr
应该定义一个数组,标准必须解决它。但是它们不是,所以就没有了。auto
推导值类型而不是引用类型的另一个例子是这样的:vectorv{1,2,3};自动i=v.前()
decltype(vector::front())
是int&
,但decltype(i)
只是普通的int
@Dennis:yes;当我们开始习惯性地使用auto
时,值得记住。这是什么原因?为什么是“标准的哪一部分这么说”,或者为什么是“委员会为什么决定这样做”?第二个原因。因为第一个为什么依赖于第二个。:)与int i=0的原因完全相同;自动a=i代码>产生一个<代码> int >代码>而不是<代码> int和<代码>。它比C++中的技巧要复杂一些,其中代码> > ARR < /COD>作为一个LValk表达式是对数组的引用,但作为一个RValk表达式衰变为一个指针……同意。但是C++编译器首先尝试遵循C规则,而不是C++规则。这就是为什么可能通过string mystring()分配局部变量的原因代码>导致错误。我也同意<代码> Auto <代码>,在新的意义上,是C++特定的,但是在模板周围需要括号来“告诉”C++编译器把它当作C++代码,而不是C代码。C++编译器首先遵循C++规则。如果他们与C语言匹配,他们也会做同样的事情,如果他们不这样做,他们将表现为C++编译器。在这种特殊情况下,如果它遵循C规则,那么定义将被解析为autointx=arr代码>,错误是无法从int*
转换为int
。我不理解 String 的情况,在C++的标准中声明了特定表达式的解析规则,它们与C标准一致,就像没有名字空间资格一样,如<代码> STD::STRI
f() is called. that means, x is an array!