我试图创建一个lambda的向量,但失败了:
auto ignore = [&]() { return 10; }; //1
std::vector<decltype(ignore)> v; //2
v.push_back([&]() { return 100; }); //3
第2行,compiles fine。但第3行给出了compilation error:
错误:没有匹配函数来调用'std :: vector&lt; main()::&lt; lambda()&gt;&gt; :: push_back(main()::&lt; lambda()&gt;)'< / p>
我不想要函数指针的向量或函数对象的向量。但是,封装真实 lambda表达式的函数对象向量对我有用。这可能吗?
答案 0 :(得分:125)
每个lambda都有不同的类型 - 即使它们具有相同的签名。如果要执行类似的操作,则必须使用运行时封装容器,例如std::function
。
e.g:
std::vector<std::function<int()>> functors;
functors.push_back([&] { return 100; });
functors.push_back([&] { return 10; });
答案 1 :(得分:39)
所有lambda表达式都有不同的类型,即使它们是逐个字符的。你正在将一个不同类型的lambda(因为它是另一个表达式)推入向量中,这显然是行不通的。
One solution是制作std::function<int()>
的矢量。
auto ignore = [&]() { return 10; };
std::vector<std::function<int()>> v;
v.push_back(ignore);
v.push_back([&]() { return 100; });
另一方面,当你没有捕捉任何东西时,使用[&]
不是一个好主意。
答案 2 :(得分:17)
虽然其他人所说的是相关的,但仍然可以声明并使用lambda的向量,虽然它不是很有用:
auto lambda = [] { return 10; };
std::vector<decltype(lambda)> vector;
vector.push_back(lambda);
所以,你可以存储任意数量的lambdas,只要它是lambda
的复制/移动!
答案 3 :(得分:15)
如果你的lambda是无状态的,即[](...){...}
,C ++ 11允许它降级为函数指针。理论上,符合C ++ 11的编译器可以编译它:
auto ignore = []() { return 10; }; //1 note misssing & in []!
std::vector<int (*)()> v; //2
v.push_back([]() { return 100; }); //3
答案 4 :(得分:3)
每个lambda都是不同的类型。您必须使用std::tuple
代替std::vector
。
答案 5 :(得分:2)
您可以使用lambda生成函数(使用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++;
}
}
但我认为你现在基本上已经成为了自己的班级。否则,如果lambda具有完全不同的caputres / args等,则可能必须使用元组。