Почему я не могу создать вектор лямбд (того же типа) в C++11?



Я пытался создать вектор лямбда, но не удалось:



auto ignore = [&]() { return 10; };  //1
std::vector<decltype(ignore)> v; //2
v.push_back([&]() { return 100; }); //3


до строки #2, это компилирует штрафа в размере. Но строка#3 дает ошибка компиляции:




ошибка: нет подходящей функции для вызова 'СТД::вектор>::push_back(основной()::)'




мне не нужен вектор указателей функций или вектор объектов функций. Однако вектор объектов функций, которые инкапсулируют реальные лямбда-выражения, будет работать для меня. Это возможно?

559   6  

6 ответов:

каждая лямбда имеет другой тип-даже если они имеют одинаковую подпись. Необходимо использовать контейнер инкапсуляции во время выполнения, например std::function Если вы хотите сделать что-то подобное.

например:

std::vector<std::function<int()>> functors;
functors.push_back([&] { return 100; });
functors.push_back([&] { return  10; });

все лямбда-выражения имеют разный тип, даже если они идентичны по символам. Вы нажимаете лямбду другого типа (потому что это другое выражение) в вектор, и это, очевидно, не будет работать.

решение это сделать вектор std::function<int()> вместо.

auto ignore = [&]() { return 10; };
std::vector<std::function<int()>> v;
v.push_back(ignore);
v.push_back([&]() { return 100; });

на другой ноте, это не хорошая идея, чтобы использовать [&] когда вы ничего не захватываете.

хотя то, что сказали другие, имеет значение, все еще можно объявить и использовать вектор лямбда, хотя это не очень полезно:

auto lambda = [] { return 10; };
std::vector<decltype(lambda)> vector;
vector.push_back(lambda);

таким образом, вы можете хранить любое количество лямбд там, пока это копия/перемещение lambda!

Если ваша лямбда не имеет состояния, т. е. [](...){...} в C++11 позволяет преобразования в указатель на функцию. Теоретически совместимый компилятор C++11 сможет скомпилировать это:

auto ignore = []() { return 10; };  //1 note misssing & in []!
std::vector<int (*)()> v;     //2
v.push_back([]() { return 100; });  //3

каждая лямбда-это другой тип. Вы должны использовать std::tuple вместо std::vector.

вы можете использовать функцию генерации лямбда (обновлено с помощью исправления, предложенного Nawaz):

#include <vector>
#include <iostream>

int main() {
    auto lambda_gen = [] (int i) {return [i](int x){ return i*x;};} ;

    using my_lambda = decltype(lambda_gen(1));

    std::vector<my_lambda> vec;

    for(int i = 0; i < 10; i++) vec.push_back(lambda_gen(i));

    int i = 0;

    for (auto& lambda : vec){
        std::cout << lambda(i) << std::endl;
        i++;
    }
}

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

Comments

    Ничего не найдено.