2014-10-15 14 views
7

Il motivo principale per i puntatori di funzione è fornire oggetti callable generici, ma in C++ 11 il modo di fornire sarebbe utilizzare std::function, quindi c'è qualche ragione per utilizzare i puntatori di funzione nel moderno C++ a parte dalla compatibilità con C? In altre parole, è std::function una versione moderna di puntatori di funzione, esattamente come std::array rispetto agli array incorporati?utilizzando i puntatori di funzioni in C++ 11

+1

perché hai chiamato i puntatori di funzione generici oggetti chiamabili? – Jamboree

+0

Intendevo che è possibile assegnare diverse funzioni con la stessa firma a un puntatore di funzione –

+1

Ci possono essere considerazioni sull'efficienza. 'std :: functions' hanno riferimenti indiretti aggiuntivi e non sono gratuiti. – juanchopanza

risposta

3

Sì, preferisco lo std::function quasi ovunque, ma ci sono alcuni casi in cui le dimensioni generali e l'indirizzamento indiretto di std::function potrebbero non essere accettabili. Per i piccoli callables come i puntatori di funzione racchiusi in std::function, in genere non esiste un'indirizzamento aggiuntivo e nessuna allocazione di memoria dinamica poiché il callable si adatta allo std::function ma std::function potrebbe essere grande per contenere anche callables più grandi, quindi potrebbe esserci un sovraccarico di spazio.

+0

Quando usereste 'std :: function' invece di solo espressioni lambda? Quando vuoi essere in grado di fornire altri tipi di implementazioni e non vuoi farlo avvolgendoli in lambda? – Jerry101

+0

@ Jerry101 Sì come i puntatori di funzione li uso per passare da diverse implementazioni o per consentire a un chiamante di fornire una sorta di funzionalità come una richiamata. Non puoi farlo con lambda perché ogni lambda ha il suo tipo. – TNA

+1

Lo scopo principale di std :: function è la cancellazione e l'adattamento dei tipi. I puntatori di funzione hanno un tipo rigoroso. std :: function è un wrapper di funzione polimorfico, può essere associato a una funzione libera, una funzione statica di classe, una funzione membro e può essere utilizzato per l'applicazione di funzioni parziali, ecc. Se non è necessario tutto ciò, probabilmente non è lo strumento giusto per il lavoro, la cancellazione del tipo non è gratuita, spesso coinvolge chiamate virtuali e allocazione dell'heap (sebbene in genere vi sia una piccola ottimizzazione del buffer). – BenPope

2

Per essere onesto, non riesco a pensare a un caso in cui avrei bisogno di std :: function, ed ecco perché. Se faccio rimbalzare i puntatori di funzione, probabilmente sto lavorando a un livello molto basso. Forse la ragione è che l'ereditarietà in stile C++ si è dimostrata troppo restrittiva, quindi sto progettando il mio stesso polimorfismo. In alternativa, potrei lavorare su un piccolo controller embedded dove sto davvero rasando i byte. Ad ogni modo, mi affiderò a me stesso, e non al compilatore, per ricordare quali tipi ho ecc. Praticamente sarei sbattuto in metallo e voglio che il metallo si comporti come metallo, non come un ascensore di Sirius Cybernetics .

L'unico caso in cui è probabile che il sovraccarico di std :: function è se sto cercando di fare qualcosa di funzionale, come le chiusure di giocoleria, ma se lo voglio, è improbabile che utilizzi C++ affatto.

+0

Java Script non è altro che chiusure e puntatori di funzioni. Non definirei questo stile di programmazione "basso livello". :) Gli elementi di programmazione funzionale sono potenzialmente utili indipendentemente dal livello basso in cui ti trovi. – Eugene

+0

* qualsiasi cosa * remotamente simile a un sistema basato su eventi sarebbe probabilmente molto meglio con 'std :: function' piuttosto che semplici puntatori di funzione. Passare in 'void *' parametri e casting non è in genere preferito: P – CoffeeandCode

1

Sui sistemi POSIX è possibile ottenere dlopen & dlsym e utilizzarli per ottenere i puntatori di funzione dai plug-in caricati dinamicamente.

Si tratta di un caso d'uso comune in cui puntatori a funzione sono ancora utili, anche con C++ 14 (si veda ad esempio Qt)

e, come molte persone hanno osservato, l'attuazione delle chiusure (o di std::function) sarebbe spesso richiedono extraindirizzamenti extra e costi extra di runtime.

1

std::function è molto pratico ed efficiente per la maggior parte dei casi d'uso. Ma c'è una caratteristica mancante: l'uguaglianza.

Quindi, ogni volta che è necessario confrontare/filtrare/cercare/ordinare std::function oggetti simili, è necessario ricorrere ai puntatori di funzione per implementare ciò che è necessario.

+0

L'uguaglianza di funzioni è in qualche modo indecidibile, se ti interessa solo il loro comportamento osservabile –

+0

Sicuro, ecco perché gli oggetti 'std :: function' non possono essere confrontati) – Stas

Problemi correlati