С++ передает массив по ссылке
разрешено ли передавать массив по ссылке?
void foo(double& *bar)
Кажется, мой компилятор говорит "нет". Зачем? Каков правильный способ передачи массива по ссылке? Или работа вокруг? У меня есть аргумент массива, который мой метод должен изменить и что я должен получить потом. В качестве альтернативы, я мог бы сделать этот массив членом класса, который отлично работает, но у него есть много недостатков для другой части моего кода (чего я бы хотел избежать).
Спасибо и приветствую.
Ответы
Ответ 1
Массивы могут передаваться только по ссылке, на самом деле:
void foo(double (&bar)[10])
{
}
Это не позволяет вам делать такие вещи, как:
double arr[20];
foo(arr); // won't compile
Чтобы передать произвольный массив размера в foo
, сделайте его шаблоном и запишите размер массива во время компиляции:
template<typename T, size_t N>
void foo(T (&bar)[N])
{
// use N here
}
Вам следует серьезно подумать об использовании std::vector
, или если у вас есть компилятор, который поддерживает С++ 11, std::array
.
Ответ 2
Да, но когда сопоставление аргументов для ссылки, неявный массив
указатель не является автоматическим, поэтому вам нужно что-то вроде:
void foo( double (&array)[42] );
или
void foo( double (&array)[] );
Помните, однако, что при сопоставлении double [42]
и double []
различные типы. Если у вас есть массив неизвестного измерения, он будет
совпадение второго, но не первого, и если у вас есть массив с 42
элементов, он будет соответствовать первому, но не второму. (Последнее,
ИМХО, очень противоречит интуиции.)
Во втором случае вам также необходимо передать измерение, поскольку
нет способа восстановить его, когда вы находитесь внутри функции.
Ответ 3
Если вы хотите изменить только элементы:
void foo(double *bar);
.
Если вы хотите изменить адрес (например: realloc
), но он не работает для массивов:
void foo(double *&bar);
- правильная форма.
Ответ 4
Поскольку вы используете С++, обязательное предложение, которое все еще отсутствует здесь, заключается в использовании std::vector<double>
.
Вы можете легко передать его по ссылке:
void foo(std::vector<double>& bar) {}
И если у вас есть поддержка С++ 11, посмотрите также std::array
.
Для справки:
Ответ 5
Как и в другом ответе, поставьте &
после *
.
Это вызывает интересный момент, который иногда может сбивать с толку: типы следует читать справа налево. Например, это (начиная с самого правого *
) указатель на константный указатель на int.
int * const *x;
То, что вы написали, должно быть указателем на ссылку, что невозможно.
Ответ 6
8.3.5.8 Если тип параметра включает тип формы "указатель на массив неизвестной границы T" или "ссылка
к массиву неизвестной границы T, "программа плохо сформирована