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

时间:2019-01-09 19:34:32

标签: c++ arrays pointers reference lvalue

据我了解,array中的int array[]={1,2,3,4,5}只是指向array第一个元素的指针。这意味着可以将array分配给类型为ptr的指针int*

int* &p中的参数hoo将通过引用传递该参数。这意味着我们可以更改传递的参数以指向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);
}

问题

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

3 个答案:

答案 0 :(得分:7)

  

根据我的理解,int array [] = {1,2,3,4,5}中的数组只是指向数组第一个元素的指针。

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

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指向的内容,从而使引用毫无意义。

答案 1 :(得分:3)

当一个函数接受一个t3 :: (m->n) -> (n->m) -> m->n t3 x y = x.y.x 参数时,即对一个指向int* &的指针的(非移动)引用-那么就需要一个真正的指针变量来该参考所指的。不能是临时指针值。因此,您不能执行以下操作:

int

因为没有指针变量要引用-只是临​​时变量。与您的int x; hoo(&x, 123); 基本相同。实际上,任何地方都没有int[5]变量-只有5个int*。当您将int传递给array时,C ++对该标识符所做的就是array-to-pointer decay:它实际上传递了hoo()。因此,就像前面的情况一样,它不会编译。

答案 2 :(得分:3)

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

使用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);
}