当 auto 用于数组时,为什么它会转换为指针而不是引用?

发布于 2024-11-16 19:41:39 字数 351 浏览 3 评论 0原文

请参阅下面的示例:

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

是否有理由为数组选择指针而不是引用

See the below example:

int arr[10];
int *p = arr; // 1st valid choice
int (&r)[10] = arr; // 2nd valid choice

Now when we use auto against arr then, it chooses the 1st choice.

auto x = arr; // x is equivalent to *p

Is there a reason for choosing a pointer and not reference for array ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

冷默言语 2024-11-23 19:41:39

是的。在该表达式中,由于左值到右值的转换,数组衰减为指针类型。

如果您想要 array 类型,而不是 pointer 类型,请执行以下操作:

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!
}

Output:

f() is called. that means, x is an array!

Demo at ideone : http://www.ideone.com/L2Ifp

请注意,f 不能指针类型调用。可以使用大小为 10int 数组来调用它。尝试使用任何其他类型调用它,将导致编译错误。

Yes. In that expression, the array decays into pointer type, due to lvalue-to-rvalue conversion.

If you want array type , not pointer type, then do this:

auto & x = arr; //now it doesn't decay into pointer type!

& in the target type prevents the array from decaying into pointer type!


x is an array and not a pointer, can be proved as:

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!
}

Output:

f() is called. that means, x is an array!

Demo at ideone : http://www.ideone.com/L2Ifp

Note that f cannot be called with pointer type. It can be called with an int array of size 10. Attempting to call it with any other type, will result in compilation error.

寻找一个思念的角度 2024-11-23 19:41:39

为了提供该行为的标准参考,7.1.6.4 [dcl.spec.auto] 第 6 段内容如下:

一旦根据 8.3 确定了 declarator-id 的类型,则使用 declarator-id 声明的变量的类型将根据其初始值设定项的类型使用模板参数推导规则来确定。令 T 为已为变量标识符 d 确定的类型。通过用新发明的类型模板参数 U 替换 auto 的出现,从 T 中获取 P ... 然后,为变量 d 推导的类型就是使用函数调用中的模板参数推导规则确定的推导 A (14.8 .2.1),其中 P 是函数模板参数类型,d 的初始值设定项是相应的参数。如果推演失败,则声明格式不正确。

所以我们需要看看其他地方,特别是 14.8.2.1 [tmp.deduct.call] 第 2 段:

如果 P 不是引用类型: — 如果 A 是数组类型,则使用数组到指针标准转换(4.2)生成的指针类型代替 A 进行类型推导

为了完整起见,4.2 [conv.array ] 第 1 段:

“NT 数组”或“T 未知边界数组”类型的左值或右值可以转换为“指向 T 的指针”类型的纯右值。结果是指向数组第一个元素的指针。

为了逐步完成它,auto x = arr; 创建一个虚构的函数 template; f(P); 并尝试从调用 f(arr) 中推导出 P。在这种情况下,A10 int 的数组,并且 P 不是引用类型,因此 A 变为 < code> 指向 int 的指针 代替。它沿着链向上渗透回到最终类型 x 。

所以基本上,它被视为一个指针,因为规则规定它必须如此。这种方式的行为更有用,因为数组是不可分配的。否则,您的 auto x = arr; 将无法编译,而不是做一些有用的事情。

To provide a standard reference for the behavior, 7.1.6.4 [dcl.spec.auto] paragraph 6 reads:

Once the type of a declarator-id has been determined according to 8.3, the type of the declared variable using the declarator-id is determined from the type of its initializer using the rules for template argument deduction. Let T be the type that has been determined for a variable identifier d. Obtain P from T by replacing the occurrences of auto with ... a new invented type template parameter U ... The type deduced for the variable d is then the deduced A determined using the rules of template argument deduction from a function call (14.8.2.1), where P is a function template parameter type and the initializer for d is the corresponding argument. If the deduction fails, the declaration is ill-formed.

So we need to look elsewhere, specifically 14.8.2.1 [tmp.deduct.call] paragraph 2:

If P is not a reference type: — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction

For completeness sake, 4.2 [conv.array] paragraph 1:

An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.

To step through it, auto x = arr; creates an imaginary function template<typename P> f(P); and attempts to deduce P from the call f(arr). A in this case is array of 10 int, and P is not a reference type, so A becomes pointer to int instead. Which percolates up the chain back into the final type of x.

So basically, it is treated as a pointer because the rules say it must. The behavior is simply more useful this way, since arrays are not assignable. Otherwise, your auto x = arr; would fail to compile rather than do something useful.

冷心人i 2024-11-23 19:41:39

auto 产生值。它不会产生参考。考虑到这一点,指针就是对数组提供的值的简单转换。

auto produces values. It will not produce references. With this in mind, then the pointer is the trivial conversion to a value that the array offers.

清浅ˋ旧时光 2024-11-23 19:41:39

对于数组arr,表达式arr本身意味着&arr[0]。该规则来自C。因此,IMO,自动选择指针。

For an array arr, the expression arr itself means &arr[0]. This rule comes from C. Therefore, IMO, auto chooses pointer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文