Perché non riesco a creare un vettore di lambda (dello stesso tipo) in C ++ 11?

Stavo cercando di creare un vettore di lambda, ma ho fallito:

auto ignore = [&]() { return 10; }; //1 std::vector v; //2 v.push_back([&]() { return 100; }); //3 

Fino alla riga n. 2, compila bene . Ma la riga 3 dà errore di compilazione :

errore: nessuna funzione di matching per la chiamata a ‘std :: vector <main () :: > :: push_back (main () :: )’

Non voglio un vettore di puntatori di funzione o vettore di oggetti funzione. Tuttavia, il vettore di oggetti funzione che racchiudono espressioni lambda reali , funzionerebbe per me. È ansible?

Ogni lambda ha un tipo diverso, anche se hanno la stessa firma. È necessario utilizzare un contenitore incapsulante di runtime come std::function se si vuole fare qualcosa del genere.

per esempio:

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

Tutte le espressioni lambda hanno un tipo diverso, anche se sono identiche carattere per carattere . Stai spingendo un lambda di un tipo diverso (perché è un’altra espressione) nel vettore, e ovviamente non funzionerà.

Una soluzione è creare un vettore di std::function .

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

In un’altra nota, non è una buona idea usare [&] quando non stai catturando nulla.

Mentre ciò che altri hanno detto è rilevante, è ancora ansible dichiarare e utilizzare un vettore di lambda, sebbene non sia molto utile:

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

Quindi, puoi memorizzare un numero qualsiasi di lambda, a patto che sia una copia / mossa di lambda !

Se il tuo lambda è stateless, cioè [](...){...} , C ++ 11 gli consente di degradarsi in un puntatore a funzione. In teoria, un compilatore compatibile con C ++ 11 sarebbe in grado di compilare questo:

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

Ogni lambda è di un tipo diverso. Devi usare std::tuple invece di std::vector .

È ansible utilizzare una funzione di generazione lambda (aggiornata con la correzione suggerita da Nawaz):

 #include  #include  int main() { auto lambda_gen = [] (int i) {return [i](int x){ return i*x;};} ; using my_lambda = decltype(lambda_gen(1)); std::vector 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++; } } 

Ma penso che tu abbia praticamente fatto la tua class a questo punto. Altrimenti se i lambda hanno caputres / args completamente diversi, probabilmente dovrai usare una tupla.