Как объявить массив лямбд

179
28 марта 2018, 05:46

Заинтересовал такой теоретический вопрос - а как объявить массив лямбд? И можно ли это сделать в принципе? Например, объявляем массив, потом в цикле заполняем его лямбдами, например, с захватом разных параметров, или еще как... Или, скажем, vector<...> - как его заполнить лямбдами?

Откровенно говоря, никогда не вдавался в такие детали, auto хватало с головой...

Answer 1

Можно воспользоваться шаблоном std::function. Но все лямбды должны быть с одинаковой сигнатурой.

std::vector<std::function<int(void)>> lambdas;
lambdas.push_back([](){ return 1; });
lambdas.push_back([](){ return 2; });
/* ... */

Если самому сигнатуру писать лениво, то можно заставить компилятор подставлять её автоматически:

auto lambda1 = [](){ return 1; };
std::vector<decltype(lambda1)> lambdas;
lambdas.push_back(lambda1 );
lambdas.push_back([](){ return 2; });

Поскольку захват переменных не оказывает влияния на сигнатуру лямбды, то можно заполнить массив вроде бы совершенно разными лямбдами:

int i0, i1;
std::vector<std::function<int(void)>> lambdas;
lambdas.push_back([](){ return -1; });
lambdas.push_back([=](){ return i0 + i1; });
lambdas.push_back([i0](){ return i0; });
lambdas.push_back([&i0](){ return i0++; });
lambdas.push_back([&](){ return i0++ + i1++; });
lambdas.push_back([&i0,i1](){ return i0++ + i1; });
/* и т.д. */
Answer 2

Например вот так:

#include <vector>
#include <functional>
#include <iostream>
int main()
{
    std::vector<std::function<int(int)>> funArray;
    for(int i = 0; i < 10; ++i)
        funArray.push_back([i](int i2) {return i2 + i;});
    for(const auto& fun : funArray)
        std::cout << "Result: " << fun(5) << "\n";
}
Answer 3

Объявить массив лямбд не сложно:

auto lambda{[](void) -> void {}};
decltype(lambda) lambdas[3]{lambda, lambda, lambda};
::std::vector<decltype(lambda)> lambdasv;
lambdasv.emplace_back(lambda);

Так как каждая лямбда имеет уникальный тип (который не зависит от ее сигнатуры), то в массиве или векторе можно будет хранить только одну и ту же лямбду:

auto lambda2{[](void) -> void {}};
decltype(lambda) lambdas[3]{lambda, lambda2, [](void) -> void {}}; // ошибка!
lambdasv.emplace_back(lambda2); // ошибка!
lambdasv.emplace_back([](void) -> void {}); // ошибка!

А после инициализации значения элементов массива изменять нельзя, так как операторы присваивания запрещены:

lambdas[2] = lambda; // ошибка
READ ALSO
Сборка драйвера OCI для Qt

Сборка драйвера OCI для Qt

Возникла необходимость подключить Oracle БД к проектуИзучил документацию и форумы - начал собирать дрова через mingw

165
Зачем использовать &ldquo;|=&rdquo;, &ldquo;&amp;=&rdquo; и т.п. в C++ вместо &ldquo;=&rdquo;?

Зачем использовать “|=”, “&=” и т.п. в C++ вместо “=”?

Програмлю Arduino и читаю в интернете про PORTГоворят, что какая-то там стабильность будет, если писать вместо = - |=, или &=

123
Работа с файлами. Выделение предложения

Работа с файлами. Выделение предложения

Всем здравствуйтеС помощью текстового редактора Блокнот создать файл

164
Что происходит при истечении SO_KEEPALIVE?

Что происходит при истечении SO_KEEPALIVE?

Что происходит c TCP-соединением при истечении таймаута SO_KEEPALIVE?

140