Есть ли способ передать значение по умолчанию в массив, который передается по ссылке на функцию, чтобы в его передаче не было необходимости?
У меня есть такая функция:
void foo(int (&arr) [3])
{
//some code...
}
Затем я попробовал это:
void foo(int (&arr) [3] = nullptr)
{
//some code...
}
но это явно не сработало, потому что ссылка не может быть nullptr и это даже не массив.
Обновлено:
Я хотел бы не использовать std::array, если это возможно, и мне также нужно знать размер передаваемого массива, не передавая его размер, поэтому я этого не сделал: int (*arr)[3].
Передать указатель int (*arr)[3] = nullptr?
void foo() { int dummy[3]; foo(dummy); }Может быть, передать std::array по указателю?
Повторно открыт, поскольку «дубликат» не отвечает, как использовать аргумент по умолчанию, в чем и заключается весь смысл этого вопроса.
Также рассмотрите void foo(const int (&arr)[3] = { 1, 2, 3 }), если вам не нужно изменять массив





В C++ нельзя напрямую передать значение по умолчанию массиву, переданному по ссылке. Однако вы можете добиться аналогичного эффекта, перегрузив функцию версией, которая принимает массив по умолчанию и вызывает с ним исходную функцию.
Вот код
void foo(int (&arr)[3]){}
void foo()
{
int defaultArr[3] = {1, 2, 3};
foo(defaultArr);
}
int main()
{
int arr[3] = {2, 1, 4};
foo(arr);
foo();
return 0;
}
Мне также нужно знать размер переданного массива, не передавая его размер, поэтому я этого не сделал:
int (*arr)[3].
Это объяснение не имеет для меня смысла. Размер массива закодирован в типе указателя. Просто коснитесь указателя, и вы получите int (&arr) [3]. Пример:
void foo(int (*arr)[3] = nullptr)
{
if (arr)
std::cout << std::size(*arr);
else
std::cout << "nullptr";
}
Таким образом, использование указателя на массив является ответом на ваш вопрос.
Другой вариант — использовать необязательный диапазон:
void foo(std::optional<std::span<int, 3>> arr = std::nullopt)
Хотя тип параметра немного более подробный, он позволяет вам передавать массив напрямую, без использования оператора addressof. Кроме того, это позволяет передавать и другие непрерывные диапазоны, а не только массивы.
Если во время компиляции вы знаете, что вам нужна опция по умолчанию, я рекомендую использовать решение для перегрузки в ответе Сайеда, но это не сработает, если опция определена во время выполнения.
Эхх "Размер массива закодирован в типе указателя" - не совсем; вы не можете получить размер массива из указателя. Для этого вам понадобится std::array или std::vector - с участником .size() вы можете вызвать.
@JesperJuhl you cannot get the size of an array from a pointer. Да, вы можете получить размер из указателя на массив. You'd need a std::array or std::vector for that Нет, они вам не нужны.
пожалуйста, продемонстрируйте получение размера массива только из указателя на первый элемент массива. Докажи, что я неправ.
@JesperJuhl Я добавил пример.
@JesperJuhl from just a pointer to the first element of an array Ваша ошибка состоит в том, что вы думаете, что int (*arr)[3] — это указатель на первый элемент массива. Это не. Это указатель на весь массив.
@JeJo Верно, но тогда у нас есть шаблон, которого OP, возможно, следует избегать. Но если шаблон не проблема, то он действительно хорош для общности. Необязательная версия диапазона может быть создана аналогичным образом.
@JeJo std::optional might require the caller side also to change/ use/ convert the arrays to optional type as well Преобразование неявное и тривиальное.
@eerorika Хорошо, спасибо, извините, что не увидела правку.
Вероятно, проще написать отдельную перегрузку
foo, которая не принимает аргумент.