Почему я не могу скопировать массив C-style в std :: array?
У меня есть этот код:
std::array<int,16> copyarray(int input[16])
{
std::array<int, 16> result;
std::copy(std::begin(input), std::end(input), std::begin(result));
return result;
}
Когда я пытаюсь скомпилировать этот код, я получаю эту ошибку:
'std::begin': no matching overloaded function found
и аналогичная ошибка для std::end
.
В чем проблема и как я могу это исправить?
Ответы
Ответ 1
В объявлении параметра int input[16]
совпадает с int* input
. И когда вы передаете массив аргументов, он будет распадаться на указатель, оба означают, что информация о размере массива теряется. И std::begin
и std::end
не могут работать с указателями.
Вы можете изменить его на передачу по ссылке, которая резервирует размер массива.
std::array<int,16> copyarray(int (&input)[16])
Обратите внимание, что вы можете передать массив только с точным размером 16
.
Ответ 2
Все важное уже сказано, вы можете сделать функцию чуть более гибкой:
template <typename T, size_t N>
std::array<T, N> copyarray(T const (&input)[N])
{
std::array<T, N> result;
std::copy(std::begin(input), std::end(input), std::begin(result));
return result;
}
(Позднее) редактирование: у подхода, описанного выше, есть недостаток: вам нужно будет копировать возвращенный массив при присваивании, так как он не содержит действительно перемещаемых данных (то же самое уже для необработанных массивов). Вы можете избежать этого недостатка, непосредственно копируя в целевой массив:
template <typename T, size_t N>
void copyarray(std::array<T, N>& target, T const (&source)[N])
{
std::copy(std::begin(source), std::end(source), std::begin(target));
}
Это имитирует назначение target = source
; если вам нравится больше, вы можете поменять местами параметры, чтобы выходной параметр был последним.
Использование (как есть):
int source[7] = { };
std::array<int, sizeof(source)/sizeof(*source)> target;
copyarray(target, source);
Ответ 3
Как уже говорилось, проблема здесь заключается в том, что массивы распадаются на указатели при передаче функции, что означает, что размер не сохраняется.
Если бы вы знали, что в массиве было 16 элементов, вы могли бы это сделать:
array<int,16> copyarray(const int input[]) {
array<int, 16> result;
copy_n(input, size(result), begin(result));
return result;
}