Why can't I create a vector of lambdas (of the same type) in C++11?
I was trying to create a vector of lambda, but failed:
auto ignore = [&]() { return 10; }; //1
std::vector<decltype(ignore)> v; //2
v.push_back([&]() { return 100; }); //3
Up to line #2, it compiles fine. But the line#3 gives compilation error:
error: no matching function for call to 'std::vector<main()::<lambda()>>::push_back(main()::<lambda()>)'
I don't want a ve开发者_如何学Pythonctor of function pointers or vector of function objects. However, vector of function objects which encapsulate real lambda expressions, would work for me. Is this possible?
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.
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
!
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
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.
Each lambda is a different type. You must use std::tuple
instead of std::vector
.
精彩评论