为什么我不能在 C + + 11中创建一个 lambdas (相同类型)的向量?

我试图创建一个 lambda 矢量,但失败了:

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 () >)’时没有匹配函数

我不需要函数指针的向量或函数对象的向量。但是,封装 真的 lambda 表达式的函数对象向量对我来说是可行的。这可能吗?

36820 次浏览

Every lambda has a different type—even if they have the same signature. You must use a run-time encapsulating container such as std::function if you want to do something like that.

e.g.:

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

All lambda expressions have a different type, even if they are identical character-by-character. You're pushing a lambda of a different type (because it's another expression) into the vector, and that obviously won't work.

One solution is to make a vector of std::function<int()> instead.

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

On another note, it's not a good idea to use [&] when you're not capturing anything.

If your lambda is stateless, i.e., [](...){...}, C++11 allows it to degrade into a function pointer. In theory, a C++11 compliant compiler would be able to compile this:

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

While what others have said is relevant, it is still possible to declare and use a vector of lambda, although it's not very useful:

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

So, you can store any number of lambdas in there, so long as it's a copy/move of lambda!

Each lambda is a different type. You must use std::tuple instead of std::vector.

You could use a lambda generating function (updated with fix suggested by 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++;
}
}

But I think you basically made your own class at this point. Otherwise if the lambdas have completely different caputres/args etc. you probably have to use a tuple.