2013-12-09 8 views

risposta

23

Il problema è che una funzione lambda in C++ può avere uno stato aggiuntivo (variabili catturate, ovvero contesto) che deve essere passato in giro per ogni istanza (possono differire per ogni istanza dell'handle con la stessa funzione lambda).

Una funzione non può avere uno stato accoppiato alla maniglia che si passa. Se si aggiungesse tale stato a un puntatore di funzione, si finisce per scrivere un wrapper che deve essere richiamabile usando la sintassi parentesi (operator()) che capita di essere ciò che è un functor.

Un fatto notevole è che una lambda senza un'acquisizione può essere convertita in un puntatore di funzione. Questo è possibile solo perché lo non richiede tale spazio aggiuntivo.

+0

Ho letto una proposta per aggiungere * catturare * conversione lambda in un puntatore a funzione la cui durata di validità è la stessa dell'istanza di chiusura. Questo è effettivamente possibile nella maggior parte delle architetture scrivendo dati che contengono istruzioni di linguaggio macchina e un puntatore al lambda, quindi contrassegnandolo come eseguibile, quindi restituendo un puntatore a quella funzione appena creata in fase di esecuzione. Non ho idea di quale sia lo stato di quella proposta. – Yakk

+0

@Yakk O semplicemente usa una variabile globale? ;) (In effetti, questo è il motivo per cui ho aggiunto l'ultima parte del primo paragrafo nella modifica della mia risposta.) – leemes

+0

più istanze del lambda con diverso stato acquisito quindi non funzionano. Fondamentalmente, su molte piattaforme, possiamo generare puntatori di funzione con stato memorizzato nel codice a cui puntano, e ci sono una miriade di API legacy che non forniscono il callback stateful void *, void (* func) (void *) paio. – Yakk

9

Le funzioni non hanno stato, quindi non sarebbero in grado di implementare la funzionalità richiesta da lambdas.

Inoltre, è garantito che lambda ha un tipo unico, che non si può veramente fare con le sole funzioni.

4

Oltre alla già citata capacità di acquisizione, anche le prestazioni sono un motivo. In generale un puntatore a funzione non può essere sottolineato. Un funtore può essere. Questo è il motivo per cui std :: sort è più veloce di qsort. Come accennato, una lambda senza catture può essere trasformata in un puntatore a funzione, ma questo è principalmente per interagire con le vecchie c api. Ad esempio, è possibile passare un lambda a una vecchia funzione win32 api. In generale, per un lambda semplice, il compilatore preferirebbe invece inserirlo in linea.

Problemi correlati