Ho scoperto che lambdas sia in MSVC che in GCC sono funtori che implementano uno operator()
. Qual è la ragione per cui preferiscono il functor ai puntatori di funzione?Perché il lambda C++ è implementato con il functor invece del puntatore di funzione?
risposta
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.
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
@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
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
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.
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.
- 1. Assegnazione del puntatore alla funzione lambda al puntatore a un'altra funzione lambda
- 2. Lambda Expression vs Functor in C++
- 3. Timer C# con lambda invece del metodo di riferimento?
- 4. Perché l'operatore() del functor stateless non può essere statico?
- 5. puntatore come secondo argomento invece di restituire il puntatore?
- 6. C: Dichiara il puntatore volatile alla funzione
- 7. sintassi puntatore funzione C
- 8. Perché non riesco a catturare il "questo" puntatore da un lambda?
- 9. I compilatori C++ possono inline un puntatore a funzione?
- 10. Come utilizzare noreturn con il puntatore funzione?
- 11. Puntatore funzione C#?
- 12. È buona pratica restituire il puntatore dalla funzione in c?
- 13. passa la funzione in base al valore (?) Invece del puntatore funzione?
- 14. Come viene implementato il comportamento del puntatore debole di azzeramento dell'ARC?
- 15. Qual è la durata dell'oggetto target del puntatore-a-funzione che punta a un lambda?
- 16. 'questo' puntatore cambia in C++ 11 lambda
- 17. Uso di lambda invece di un oggetto funzione, cattiva prestazione
- 18. È possibile associare il secondo parametro di una funzione lambda?
- 19. Perché java.util.concurrent.atomic.AtomicBoolean è implementato internamente con int?
- 20. Perché non può for_each modificare l'argomento del suo functor?
- 21. nascosto in C# con un esempio valido. perché è implementato nel framework? qual è il vantaggio del mondo reale?
- 22. Posso scrivere un functor C++ che accetta sia un puntatore raw sia un puntatore intelligente?
- 23. Utilizzando gli algoritmi STL, è meglio passare un puntatore a funzione o un functor?
- 24. Come è implementato il fractions.limit_denominator di python?
- 25. Qual è il tipo di una funzione lambda?
- 26. Il decadimento lambda deve funzionare con il puntatore nel codice di modello?
- 27. Perché il tipo di dati booleani non è stato implementato in C
- 28. Qual è il vantaggio delle "espressioni lambda"?
- 29. perché usa il movl invece di premere?
- 30. Dichiarazione ricorsiva del puntatore funzione in C
Perché lo standard dice così? Hanno bisogno di spazio anche per le catture. – chris