Почему я не могу создать вектор lambdas (одного типа) в С++ 11?
Я пытался создать вектор лямбда, но не удалось:
auto ignore = [&]() { return 10; }; //1
std::vector<decltype(ignore)> v; //2
v.push_back([&]() { return 100; }); //3
До строки # 2, компилируется отлично. Но строка # 3 дает ошибку компиляции:
Ошибка: нет соответствующей функции для вызова std::vector < main():: < lambda() → :: push_back (main():: < lambda() > ) '
Мне не нужен вектор указателей функций или вектора объектов функции. Однако вектор объектов функций, которые инкапсулируют реальные лямбда-выражения, будет работать для меня. Возможно ли это?
Ответы
Ответ 1
Каждая лямбда имеет другой тип - даже если у них одинаковая подпись. Вы должны использовать контейнер инкапсуляции времени выполнения, такой как std::function
если вы хотите сделать что-то подобное.
например:
std::vector<std::function<int()>> functors;
functors.push_back([&] { return 100; });
functors.push_back([&] { return 10; });
Ответ 2
Все лямбда-выражения имеют другой тип, даже если они идентичны по характеру. Вы подталкиваете лямбда другого типа (потому что это другое выражение) в вектор, и это явно не сработает.
Одно из решений состоит в том, чтобы сделать вместо этого вектор std::function<int()>
.
auto ignore = [&]() { return 10; };
std::vector<std::function<int()>> v;
v.push_back(ignore);
v.push_back([&]() { return 100; });
В другой заметке не рекомендуется использовать [&]
, когда вы ничего не захватываете.
Ответ 3
В то время как то, что говорили другие, актуально, все же можно объявить и использовать вектор лямбда, хотя это не очень полезно:
auto lambda = [] { return 10; };
std::vector<decltype(lambda)> vector;
vector.push_back(lambda);
Итак, вы можете хранить любое количество лямбда там, если оно копирует/перемещает lambda
!
Ответ 4
Если ваша лямбда не имеет состояния, т.е. [](...){...}
, С++ 11 позволяет деградировать в указатель функции. Теоретически компилятор, совместимый с С++ 11, мог бы скомпилировать это:
auto ignore = []() { return 10; }; //1 note misssing & in []!
std::vector<int (*)()> v; //2
v.push_back([]() { return 100; }); //3
Ответ 5
Каждая лямбда - это другой тип. Вы должны использовать std::tuple
вместо std::vector
.
Ответ 6
Вы можете использовать функцию генерации лямбда (обновленную с помощью исправления, предложенной 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++;
}
}
Но я думаю, что вы в основном создали свой собственный класс на данный момент. В противном случае, если у lambdas есть совершенно разные caputres/args и т.д., Вам, вероятно, придется использовать кортеж.