Передача массива в лямбда-функцию - PullRequest
0 голосов
/ 11 сентября 2018

В настоящее время я изучаю, как работают лямбда-функции, и поэтому пытаюсь передать массив в лямбда-функцию, где я хочу распечатать его. Моя проблема в том, что я не понимаю, как передать массив в функцию. Проблема, кажется, коренится в преобразовании массива, когда он передается лямбда-функции. Это текущее состояние функции:

auto print_array = [](int &array, int i) -> int {

    //print out array

    return 0;

}(&actual_array, actual_i);

Помощь высоко ценится!

Ответы [ 3 ]

0 голосов
/ 11 сентября 2018

Объявите лямбда-переменную, которая принимает массив (и длину) в качестве параметров;

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);
0 голосов
/ 11 сентября 2018

Вы не можете передать массив по значению, и ваш синтаксис для передачи указателя неверен.

Хотя на самом деле легко передать указатель или ссылку на массив.Используя общие лямбды, вы можете игнорировать тот факт, что измерение является частью типа, и просто написать:

#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);
}

Ни один изэто специфично для лямбд.То же самое для любой функции.

0 голосов
/ 11 сентября 2018

Массив не может быть аргументом функции.

Кроме того, ссылка 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].


P.S. «распечатка» массива звучит как то, что не нужно модифицировать массив. Учтите это и, если возможно, используйте const указатель на первый элемент или const ссылку в качестве аргумента.

Обратите внимание, что оболочка std::array является классом, а не массивом. Таким образом, std::wrapper не неявно затухает до указателя, и std::array может использоваться в качестве аргумента функции, если это необходимо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...