Non si può mai sapere il tipo di funzione lambda perché ciò che accade logicamente è il compilatore genera una classe (locale) con la funzione l'operatore di chiamata è sovraccarico e una chiusura lessicale è rappresentata dai membri dati di quella classe (locale). Questo è ciò che accade logicamente per una funzione lambda come ad esempio:
auto foo = [](int x, int y) { return x + y; };
Il compilatore fa logicamente questo:
struct CompilerGeneratedName { void operator()(int x, int y) const { return x + y; } };
CompilerGeneratedName foo;
Dal momento che il compilatore genera una classe (locale), si genera un nome e quindi si può non scrivere mai esplicitamente il tipo, puoi solo dedurlo dal tipo deduzioni degli argomenti della funzione template o usando auto/decltype.
Anche le chiusure di C++ 0x sono allocate staticamente, quindi non è possibile restituire in modo sicuro una chiusura raw di C++ 0x.
Ancora ci sono alcuni modi per ottenerlo, il primo è più flessibile e supporta le funzioni lambda che catturano gli ambiti lessicali. Usa la funzione std :: se hai una funzione lambda che non cattura nulla dall'ambito esterno allora puoi usare i puntatori di funzione, ma questa conversione è più utile per lavorare con il codice legacy che altro.
Quindi, in pratica ciò che si vuole è questo:
std::function< int (int) > foo(int x)
{
return [x](int y)->int{return x * y;};
}
Il motivo per cui ho continuato a dire logicamente, è perché questo è come boost :: lambda tipo di opere originariamente (anche se C++ 03 non consente alle classi locali di essere utilizzate negli argomenti della funzione template) e da dove proviene l'idea di aggiungere funzioni lambda, ma poiché questa è una funzione linguistica ora i produttori di compilatori potrebbero implementarla in modi diversi e più efficienti come quando si acquisisce tutto l'ambiente facendo riferimento al compilatore può semplicemente passare un puntatore allo stack di chiamate invece del modo logico mantenendo comunque la vista logica.
fonte
2010-07-01 20:21:42
Grazie, +1. Cosa intendi con "se la funzione lambda non cattura nulla dall'ambito esterno, allora puoi usare i puntatori di funzione".? Non sta catturando la x? – Cam
@incrediman sì il tuo esempio è in acquisizione quindi non è possibile utilizzare i puntatori di funzione, solo le funzioni lambda che sono stateless possono essere convertite in puntatori di funzioni. –
@snk_kid: Oh. In realtà ho solo interpretato erroneamente ciò che hai scritto, ha perfettamente senso così com'è :) – Cam