为什么我们不能将 int array[] 传递给 hoo(int* &p)?

Why can't we pass int array[] to hoo(int* &p)?

在我的理解中,int array[]={1,2,3,4,5}中的array只是指向array的第一个元素的指针。这意味着 array 可以分配给 int*.

类型的指针 ptr

hoo 中的参数 int* &p 将通过引用传递参数。这意味着我们可以更改传递的参数以指向 hoo 中的另一个值。

void hoo(int* &p, int n)
{
    for (int i = 0; i < n; i++)
        cout << p[i] << endl;
}

int main()
{
    int array[] = { 1,2,3,4,5 };

    // I can do this
    int* ptr = array;
    hoo(ptr, 5);

    // but not this.
    //hoo(array, 5);
}

问题

为什么我们不能在没有 ptr 的情况下将 int array 传递给 hoo

In my understanding array in int array[]={1,2,3,4,5} is just a pointer to the first element of array.

这是不正确的。数组是数组,指针是指针。它们是具有不同属性的不同类型。他们经常感到困惑,因为数组具有 属性,它会急切地衰减到指向其第一个元素的指针。

hoo(array, 5); 尝试将 array 转换为 int*,但该转换的结果是右值,不能绑定到非 const 引用.例如,如果您将 hoo 更改为采用 const 引用,它将编译正常:

void hoo(int* const &p, int n) { }

int main()
{
    int array[] = { 1,2,3,4,5 };
    hoo(array, 5);
}

在那种情况下,您无法更改 p 指向的内容,从而使引用毫无意义。

当一个函数接受一个 int* & 参数时,也就是说,一个(非移动)引用指向一个 int 的指针 - 然后需要一个真正的指针该引用所指的变量。它不能是临时指针值。因此你不能这样做:

int x;
hoo(&x, 123);

因为没有可引用的指针变量 - 只是临时变量。这与您的 int[5] 本质上是一样的。实际上任何地方都没有 int* 变量——只有 5 个 int。当您将 array 传递给 hoo() 时,C++ 使用该标识符所做的是一个 array-to-pointer decay:它实际上传递了 &(array[0])。所以就像前面的例子一样,那不会编译。

其他答案已经说明问题了。我想建议更改编码实践。

使用void hoo(int* &p, int n)作为函数声明是非常古老的风格。使用模板,您可以让编译器推断大小并获得对数组的引用,从而避免使用指针。

template <size_t N>
void hoo( int (&p)[N]) // The argument is a reference to an array of N elements.
{
    for (int i = 0; i < N; i++)
        cout << p[i] << endl;
}

函数的调用变得自然。

int array[] = { 1,2,3,4,5 };
hoo(array);

如果您的函数也需要能够支持动态分配的数组,您可以按如下方式重载该函数。

void hoo(int* p, size_t N)
{
    for (int i = 0; i < N; i++)
        cout << p[i] << endl;
}

template <size_t N>
void hoo( int (&p)[N]) // The argument is a reference to an array of N elements.
{
    hoo(p, N);
}