Передача массива по ссылке


184

Как работает передача статически размещенного массива по ссылке?

void foo(int (&myArray)[100])
{
}

int main()
{
    int a[100];
    foo(a);
}

Имеет ли (&myArray)[100]какой-либо смысл или это просто синтаксис для передачи любого массива по ссылке? Я не понимаю отдельных скобок, за которыми следуют большие скобки. Спасибо.


Есть ли отношение Rvalue к Lvalue с параметрами функции?
Джон Д.Б.


Ответы:


228

Это синтаксис для ссылок на массивы - вам нужно использовать, (&array)чтобы уточнить компилятору, что вы хотите ссылаться на массив, а не на (недопустимый) массив ссылок int & array[100];.

РЕДАКТИРОВАТЬ: некоторые уточнения.

void foo(int * x);
void foo(int x[100]);
void foo(int x[]);

Эти три разных способа объявления одной и той же функции. Все они рассматриваются как принимающие int *параметр, вы можете передать им массив любого размера.

void foo(int (&x)[100]);

Это принимает только массивы из 100 целых чисел. Вы можете безопасно использовать sizeofнаx

void foo(int & x[100]); // error

Это анализируется как «массив ссылок» - что не является законным.


Почему мы не можем иметь массив ссылок, например int a, b, c; int arr[3] = {a, b, c};?
Ворак

4
Ага, выяснил почему .
Ворак

2
Может кто-нибудь объяснить, почему void foo(int & x[100]);анализируется как "массив ссылок", пожалуйста? Это потому, что правило "справа налево"? Если да, кажется, что это не соответствует тому, как void foo(int (&x)[100]);анализируется как «ссылка на массив». Заранее спасибо.
zl9394

3
Это не справа налево, это наизнанку, и [] связывается сильнее, чем &.
Philipxy

48

Это просто необходимый синтаксис:

void Func(int (&myArray)[100])

^ Передать массив из 100 intпо ссылке имя параметра myArray;

void Func(int* myArray)

^ Передайте массив. Массив распадается на указатель. Таким образом вы теряете информацию о размере.

void Func(int (*myFunc)(double))

^ Передать указатель на функцию. Функция возвращает intи принимает double. Имя параметра есть myFunc.


Как мы передаем массив переменного размера в качестве ссылки?
Шивам Арора

@ShivamArora Вы шаблонизируете функцию и делаете размер параметром шаблона.
Мартин Йорк,

24

Это синтаксис. В аргументах функции необходимы int (&myArray)[100]скобки, заключающие в себя &myArray. если вы не используете их, вы будете передавать, array of referencesи это потому, что subscript operator []имеет более высокий приоритет над & operator.

Например int &myArray[100] // array of references

Таким образом, используя его, type construction ()вы сообщаете компилятору, что вам нужна ссылка на массив из 100 целых чисел.

Например int (&myArray)[100] // reference of an array of 100 ints


«если вы их не используете, вы будете передавать array of references» - что, конечно, не может существовать, поэтому вы получите ошибку компиляции. Мне забавно, что правила приоритета операторов настаивают, что это должно произойти по умолчанию в любом случае.
underscore_d

Есть ли еще учебник о конструкции типа ()?
Главный Shifter

Спасибо, мне нужно было объяснение, которое включало причину приоритета оператора, чтобы понять, почему это нужно сделать таким образом.
cram2208

4

Массивы по умолчанию передаются указателями. Вы можете попробовать изменить массив внутри вызова функции для лучшего понимания.


2
Массивы не могут быть переданы по значению. Если функция получает указатель, массив распадается на указатель на свой первый элемент. Я не уверен, что вы пытаетесь сказать здесь.
Ульрих Экхардт

@UlrichEckhardt Я пытаюсь сказать, что «Массивы не могут быть переданы по значению», как вы сказали ранее, они по умолчанию передаются по ссылке
Эдуардо А. Фернандес Диас

8
Массив не передается ни по значению, ни по ссылке. Они передаются указателями. Если по умолчанию массивы передаются по ссылке, у вас не возникнет проблем с использованием sizeof. Но это не тот случай. Массивы распадаются на указатели при передаче в функцию.
user3437460

2
Массивы могут быть переданы по ссылке ИЛИ путем понижения указателя. Например, использование char arr[1]; foo(char arr[]).arr ухудшает указатель; при использовании char arr[1]; foo(char (&arr)[1])arr передается как ссылка. Примечательно, что первая форма часто рассматривается как плохо сформированная, так как измерение потеряно.
zl9394

Re, "Массивы ... передаются указателями." Это описание звучит в лучшем случае нетрадиционно, и это может сбить с толку новичков. Имя из переменного массива, является допустимым выражением, значение которого является Пиковым первым элементом массива. Если у вас есть какая-то функция foo(T* t)и у вас есть массив, T a[N];тогда, когда вы пишете, foo(a);я думаю, было бы правильнее сказать, что вы передаете указатель, а не массив, и вы передаете указатель по значению.
Соломон Слоу

1

Следующее создает обобщенную функцию, принимая массив любого размера и любого типа по ссылке:

template<typename T, std::size_t S>
void my_func(T (&arr)[S]) {
   // do stuff
}

играть с кодом.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.