私はラムダのベクトルを作成しようとしましたが、失敗しました:
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()>)」の呼び出しに一致する関数がありません
関数ポインターのベクトルまたは関数オブジェクトのベクトルは必要ありません。ただし、realラムダ式をカプセル化する関数オブジェクトのベクトルは、私にとってはうまくいくでしょう。これは可能ですか?
すべてのラムダには、同じシグネチャがある場合でも、異なるタイプがあります。そのようなことをしたい場合は、std::function
などのランタイムカプセル化コンテナを使用する必要があります。
例えば。:
std::vector<std::function<int()>> functors;
functors.Push_back([&] { return 100; });
functors.Push_back([&] { return 10; });
すべてのラムダ式は、タイプが異なります文字ごとに同じ場合でも。異なる型のラムダを(別の式であるため)ベクトルにプッシュしており、明らかに動作しません。
1つの解決策 は、代わりにstd::function<int()>
のベクトルを作成することです。
auto ignore = [&]() { return 10; };
std::vector<std::function<int()>> v;
v.Push_back(ignore);
v.Push_back([&]() { return 100; });
別の注意として、何もキャプチャしていないときに[&]
を使用するのは得策ではありません。
他の人が言ったことは関連していますが、ラムダのベクトルを宣言して使用することはまだ可能ですが、あまり有用ではありません:
auto lambda = [] { return 10; };
std::vector<decltype(lambda)> vector;
vector.Push_back(lambda);
したがって、lambda
のコピー/移動である限り、そこに任意の数のラムダを格納できます。
ラムダがステートレス、つまり[](...){...}
の場合、C++ 11ではラムダを関数ポインターに分解できます。理論的には、C++ 11準拠のコンパイラはこれをコンパイルできます。
auto ignore = []() { return 10; }; //1 note misssing & in []!
std::vector<int (*)()> v; //2
v.Push_back([]() { return 100; }); //3
ラムダ生成関数を使用できます(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++;
}
}
しかし、この時点で基本的に独自のクラスを作成したと思います。そうでない場合、ラムダのcaputres/argsなどが完全に異なる場合は、おそらくタプルを使用する必要があります。
各ラムダは異なるタイプです。 std::Tuple
の代わりにstd::vector
を使用する必要があります。