Ответ 1
Параметр reference-to-array не позволяет разбить тип массива на тип указателя. т.е. точный тип массива сохраняется внутри функции. (Например, вы можете использовать трюк sizeof arr / sizeof *arr
для параметра и получить счетчик элементов). Компилятор также проведет проверку типов, чтобы убедиться, что тип аргумента массива точно такой же, как тип параметра массива, т.е. Если параметр объявлен как массив из 10 целых чисел, аргумент должен быть массивом точно равным 10 ints и ничего больше.
Фактически, в ситуациях, когда размер массива фиксирован во время компиляции, использование объявлений параметров reference-to-array (или указателя-массива) может быть воспринято как первичный, предпочтительный способ передать массив. Другой вариант (когда тип массива разрешен для разложения на тип указателя) зарезервированы для ситуаций, когда необходимо передать массивы времени выполнения.
Например, правильный способ передать массив размера времени компиляции для функции
void foo(int (&arr)[10]); // reference to an array
или
void foo(int (*arr)[10]); // pointer to an array
Несомненно, неправильный способ заключается в использовании "затухающего" подхода
void foo(int arr[]); // pointer to an element
// Bad practice!!!
"Затухающий" подход должен быть обычно зарезервирован для массивов времени выполнения и обычно сопровождается фактическим размером массива в отдельном параметре
void foo(int arr[], unsigned n); // pointer to an element
// Passing a run-time sized array
Другими словами, на самом деле нет "почему", когда речь идет о передаче меток-к-массиву (или указателю на массив). Вы должны использовать этот метод естественным образом, по умолчанию, когда это возможно, если размер массива фиксирован во время компиляции. Вопрос "почему" должен действительно возникать, когда вы используете "разложившийся" метод передачи массива. "Разложившийся" метод предполагается использовать только как специализированный трюк для передачи массивов времени выполнения.
Вышеприведенное является в основном прямым следствием более общего принципа. Когда у вас есть "тяжелый" объект типа T
, вы обычно передаете его либо указателем T *
, либо ссылкой T &
. Массивы не являются исключением из этого общего принципа. У них нет причин быть.
Имейте в виду, что на практике часто имеет смысл писать функции, которые работают с массивами времени выполнения, особенно когда речь заходит об общих, библиотечных функциях. Такие функции более универсальны. Это означает, что часто есть веская причина использовать "разложившийся" подход в реальном коде жизни. Тем не менее это не оправдывает автора кода от распознавания ситуаций, когда размер массива известен во время компиляции и с использованием ссылки на -array соответственно.