Почему ссылка на массив не работает, пока мы не используем указатель?

Это работает очень хорошо...

int a[5] = {1,2,3,4,5}, int *p = a;
int *& ref = p;

Но почему это не работает?

int a[5] = {1,2,3,4,5};
int*& ref = a;

Оба a и p являются указателями и имеют одинаковое значение (адрес a[0]). Когда я ссылаюсь на массив с помощью указателя (p), он работает очень хорошо.

Но когда я напрямую ссылаюсь на этот массив a[], он не работает... Почему?

Ответ 1

a не является указателем, это массив. Он имеет тип int[5]. То, что он может сделать, это распад на указатель int*, что и происходит в первом случае. Поэтому, ссылаясь на p, это нормально.

Теперь для второго случая. Помните, что a не является указателем. Таким образом, происходит неявное преобразование от int[5] до int*. Результатом этого преобразования является prvalue. Но вы не можете привязать ссылку non-const lvalue (которая является тем, что ref) к rvalue! Таким образом, код не скомпилируется.

Здесь аналогия:

double a = 1.4;
int& b = a; // implicit conversion from 'double' to `int` results in prvalue
            // and you can't bind non-const lvalue refs to rvalues.

Ответ 2

Добавив к тому, на что уже был дан ответ, вы можете получить ссылку на массив вроде

int a[5];
int (&ref)[5] = a;

Live

Ответ 3

int*& ref = a;

int* - тип указателя, а не тип массива. Итак, почему он не привязывается к a, который имеет тип int[5].

Итак, используйте const

int* const& ref = a;

Он отлично работает. Поскольку имя массива является постоянной адреса, ссылка не константа не может ссылаться на константу.