Gli oggetti hanno vite; funzioni no. Le funzioni non vivono o muoiono; esistono sempre. In quanto tale, una funzione non può andare "fuori dallo scope", né la funzione puntata da un puntatore a funzione precedentemente valido può svanire. Indipendentemente da dove provengono, i puntatori di funzione sono sempre validi.
Ora, questo ignora il caricamento dinamico e così via, ma questo è un comportamento extra standard.
Il puntatore a funzione che si ottiene da una lambda è un puntatore a funzione. Non è speciale o magico. Pertanto non si comporta in modo diverso da qualsiasi altro puntatore di funzione.
E 'possibile che il risultato della conversione a void (*)) punti (a qualcosa che richiama una funzione membro legata ad un oggetto?
Questa è una domanda molto più complessa.Uno su cui lo standard sembra piuttosto sottostimato. Lo standard dice solo:
l'indirizzo di una funzione che, quando invocato, ha lo stesso effetto del richiamo dell'operatore di chiamata di funzione del tipo di chiusura.
Che "lo stesso effetto" significa esattamente è la domanda. Si potrebbe sostenere che "lo stesso effetto" significa fare quello che avrebbe fatto la funzione chiamata operatore, eseguendo la stessa sequenza di istruzioni. Si potrebbe anche sostenere che "lo stesso effetto" significherebbe invocare l'oggetto di chiusura stesso.
Quest'ultimo caso può sembrare difficile da implementare, ma ricorda che è possibile utilizzare la magia del compilatore. La chiusura potrebbe restituire un puntatore di funzione specifico dell'istanza, assegnato dalla chiusura su richiesta. O qualcuno-così.
Il testo non normativo non sembra essere molto imminente su questo argomento. V'è un esempio di una chiusura per un lambda (generico), che dice questo:
template<class T> auto operator()(T t) const { ... }
template<class T> static auto lambda_call_operator_invoker(T a) {
// forwards execution to operator()(a) and therefore has
// the same return type deduced
...
}
Il commento in questione suggerisce spedizioni, ma che richiederebbe che la chiamata statica costruire una nuova istanza della lambda per fare l'inoltro con.
Nel complesso, lo standard non chiarisce se chiamare il puntatore di funzione generato dopo la distruzione della chiusura è legale.
Interessante domanda. Poiché il puntatore punterà ad un membro * statico * "invoker", il membro statico non ha altra scelta che usare qualche oggetto fittizio per richiamare l'operatore() 'del lambda (perché quest'ultimo non è statico). Quel manichino dovrebbe essere locale al "invocatore", o statico, cioè dovrebbe funzionare bene nel contesto di cui sopra. Ma non vedo immediatamente quella garanzia nelle specifiche del linguaggio. Le specifiche del linguaggio non postulano nemmeno l'esistenza di quell'oggetto fittizio. – AnT
@ant Perché? Somply deve eseguire lo stesso codice. Perché deve essere in 'operator()'? 'operator()' potrebbe essere implementato chiamando la funzione statica che 'operator void (*)()()' restituisce – Yakk
Vorrei che tutte le domande "prolisso" fossero brevi –