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

时间:2011-09-19 21:08:07

标签: c++ vector lambda c++11

我试图创建一个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表达式的函数对象向量对我有用。这可能吗?

6 个答案:

答案 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等,则可能必须使用元组。