В настоящее время я изучаю, как работают лямбда-функции, и поэтому пытаюсь передать массив в лямбда-функцию, где я хочу распечатать его. Моя проблема в том, что я не понимаю, как передать массив в функцию. Проблема, кажется, коренится в преобразовании массива, когда он передается лямбда-функции. Это текущее состояние функции:
auto print_array = [](int &array, int i) -> int {
//print out array
return 0;
}(&actual_array, actual_i);
Помощь высоко ценится!
Вы не можете передать массив по значению, и ваш синтаксис для передачи указателя неверен.
Хотя на самом деле легко передать указатель или ссылку на массив. С общими лямбдами вы можете игнорировать тот факт, что измерение является частью типа, и просто написать:
#include <iostream>
int main()
{
int actual_array[5] = {7,8,9,2,1};
const int actual_i = 3;
auto print_array = [](auto& ar, int i) {
std::cout << ar[i] << '\n';
};
print_array(actual_array, actual_i);
}
В этом примере print_array
экземпляр, который вы называете, принимает int(&)[5]
скрытый за auto&
,
Если по какой-то причине вы не можете придерживаться общей лямбды (которая в основном является шаблоном), тогда переходите к старой школе:
#include <iostream>
int main()
{
int actual_array[5] = {7,8,9,2,1};
const int actual_i = 3;
auto print_array = [](const int* ar, int i) {
std::cout << ar[i] << '\n';
};
print_array(&actual_array[0], actual_i);
}
Ничто из этого не относится к лямбдам. То же самое для любой функции.
Объявите лямбда-переменную, которая принимает массив (и длину) в качестве параметров;
using namespace std;
auto print_array = [](const int *items, int length) {
for (int i = 0; i < length; i++)
{
cout << items[i] << endl;
}
};
Вызывать:
int myArray[] = { 11,22,33,44 };
print_array(myArray, 4);
Массив не может быть аргументом функции.
Кроме того, int
ссылка не может привязываться к массиву int
, Также нельзя использовать целочисленную ссылку в качестве массива.
Тем не менее, указатель может быть доступен с помощью оператора индекса почти так же, как массив. Имя массива фактически неявно преобразуется в указатель на первый элемент. Это преобразование называется распадом:
int array[n];
int* ptr_to_first_element = array;
assert(ptr_to_first_element[i] == array[i]);
Таким образом, вы можете использовать целочисленный указатель в качестве аргумента функции и передать указатель на первый элемент массива:
void foo(int *array, std::size_t size);
// ...
int array[n];
foo(array, n);
Все вышесказанное относится и к лямбдам. Чтобы вы могли написать:
auto print_array = [](int *array, int i) -> int {
// ^ notice this
//print out array using the pointer
return 0;
}(&actual_array, actual_i);
Вы Можно однако в качестве аргумента функции укажите ссылку на массив определенного размера:
void foo(int (&array)[20]);
Это немного ограничивает, поскольку ссылка может связываться только с массивом одного определенного размера. Шаблон упрощает создание такой функции для любого размера массива:
template<std::size_t size>
void foo(int (&array)[size]);
Полиморфные лямбды (введенные в C ++ 14) значительно упрощают это:
int actual_array[10];
auto print_array = [](auto &array, int i) -> int {
// ^^^^^^ notice this
//print out the referred array
return 0;
}(&actual_array, actual_i);
В этом случае тип array
аргумент будет выведен, чтобы быть int (&)[10]
,
Постскриптум «распечатка» массива звучит как то, что не нужно модифицировать массив. Подумайте об этом и, если возможно, используйте const
указатель на первый элемент или const
ссылка в качестве аргумента.
Обратите внимание, что std::array
Оболочка — это класс, а не массив. В качестве таких, std::wrapper
неявно затухает до указателя, и std::array
может быть использован в качестве аргумента функции, если это необходимо.