Страницы

Поиск по вопросам

среда, 18 декабря 2019 г.

Передача массива в функцию и range-based цикл

#cpp #массивы #указатели #cpp11


Весь мозг поломал, перечитал все об указателях и так и не понял как сделать этот
код работоспособным. Как прямо сказать циклу что я ему подсовываю именно массив (а
то он ругается что не найдена функция begin)?

void func (int * a)
{
     for (auto n : a) { std::cout << n; }   
}

int main() {

    int arr[] = { 4,7,3,4,7,8,9,0};
    func(arr);
}

    


Ответы

Ответ 1



Поскольку вы передаете указатель (да даже если бы вы передали массив без указания размера - все равно передался бы указатель), таким образом - никак. Указатель не несет в себе никакой информации, кроме адреса. func никак не может узнать, где конец массива. Поскольку в вопросе именно range-based цикл, то тривиальную передачу указателя, количества элементов и обычный цикл не рассматриваем. Но и тут можно выкрутиться - с помощью шаблонов: template void func(T (&a)[N]) { for (auto n : a) { std::cout << n << " "; } } int main() { int arr[] = { 4,7,3,4,7,8,9,0}; func(arr); }

Ответ 2



@Harry. Стоит отметить, что в Вашем, очень изящном решении, в функцию передается не указатель на массив (как в исходном вопросе), а ссылка на массив известного размера. Именно такую рекомендацию дает Страуструп в четвертом издании своей книги (12.2.2, page 318): If you really want to pass an array, rather than a container or a pointer to the first element of an array, you can declare a parameter of type reference to array. Если не использовать шаблоны, то получим набор перегруженных функций - по одной на каждый размер передаваемого массива (и каждого типа массива). В предложенном же решении размер массива, передаваемого в функцию, будет известен в результате выполнения процедуры конкретизации (instantiation) шаблона функции.

Ответ 3



Чтобы произвольные коллекции, а не только массивы в range-циклы передать, можно template-функцию использовать: #include template void func(Range&& range) { for(auto&& v : range) { std::cout << v; } } int main() { int arr[] = { 4,7,3,4,7,8,9,0}; func(arr); } Пример: $ make CXX='g++ -std=c++11' main && ./main g++ -std=c++11 main.cc -o main 47347890 See C++11: Defining Function With Container Parameter (like range-based for)?

Комментариев нет:

Отправить комментарий