2009-10-06 15 views
18

Sono a conoscenza dei seguenti approcci ai delegati C++:Fast Delega C++

. Interfacce con pure funzioni virtuali
. Boost.Function
. The Fastest Possible C++ Delegates
. The Impossibly Fast C++ Delegates
. Fast C++ Delegates
. Fast C++ Delegate: Boost.Function 'drop-in' replacement and multicast

Ciascuno ha i suoi pro e contro. Alcuni sono più veloci, altri più flessibili, altri più ricchi di funzionalità, alcuni sono più conformi agli standard e altri sono più portatili, ma personalmente mi trovo affezionato al terzo: Delegato di C++ impossibilmente veloce di Sergey Ryazanov. Il problema però è che i suoi delegati non sono comparabili:

I miei delegati non possono essere confrontati. Gli operatori di confronto non sono definiti perché un delegato non contiene un puntatore al metodo. Il puntatore a una funzione stub può essere diverso in varie unità di compilazione.

Per quale i lettori hanno risposto:

"puntatore ad una funzione stub può essere diversa nelle varie unità di compilazione". AFAIK, questo non è vero. I compilatori sono tenuti a riutilizzare le funzioni del modello generate in diverse unità di compilazione (ne sono sicuro, ma credo che Borland abbia violato una volta questa regola). Penso che sia perché le classi (quelle che non sono nei namespace "senza nome") usano il linkage esterno e il modo in cui si usano le funzioni di stub impedirà sempre che siano inline (anche se questo non dovrebbe essere un problema come prendere l'indirizzo della funzione costringerà una versione non inline da generare e il 'linkage esterno' eseguito dal linker eliminerà tutte le funzioni tranne uno identiche (vengono assunte e richieste per essere identiche dallo standard) ...

Se si definisci una funzione template una unità di traduzione (file cpp) e quindi definisci la stessa funzione in modo diverso in un'altra unità di traduzione, solo una delle due versioni la renderà nell'eseguibile finale. (Questo in realtà viola la "One Definition Rule", ma funziona su GCC, almeno ... non sono sicuro di MSVC.) Il punto è: l'indirizzo [dello stub] sarà lo stesso in diverse unità.

Vorrei esortare l'utente ad aggiornare l'articolo (compresa la capacità di confronto) se si ritiene che ciò sia vero per MSVC - se MSVC è un conferimento standard, a tale riguardo.

Ora l'articolo è di quattro anni e l'autore non ha risposto a nessuna delle osservazioni nel corso degli ultimi tre anni o giù di lì, quindi mi chiedo se c'è qualche merito al commento di cui sopra e se questo specifico l'implementazione può essere effettivamente modificata per supportare i confronti. Lo standard C++ proibisce specificamente tale utilizzo e, in tal caso, alcuni dei recenti compilatori sono effettivamente conformi agli standard in questo senso?

Grazie.

+1

Anche se l'affermazione era vera, la comparabilità può essere facilmente aggiunta aggiungendo un membro altrimenti inutilizzato ai suoi delegati. – MSalters

risposta

11

Il codice è sia standard che soddisfacente. Non vedo alcun luogo in cui egli violi l'ODR, ed è vero che tutte le istanze di un modello di funzione con gli stessi parametri del modello dovrebbero avere "lo stesso indirizzo" (nel senso che i puntatori alle funzioni dovrebbero essere tutti uguali) - come questo risultato non è importante. ISO C++ 03 14.5.5.1 [temp.over.link] descrive le regole in modo più dettagliato.

Quindi, un confronto potrebbe essere ben definito lì in modo conforme e portatile.

+0

Cosa succede se le istanze del modello risiedono in DLL diverse? O uno nell'applicazione principale e altri in DLL diverse? – user1095108

+0

Lo standard non si occupa veramente della nozione di librerie DLL/condivise. In pratica, ovviamente, dal momento che sono compilati e collegati separatamente, non c'è modo per i compilatori di unire le istanze. Quindi, sì, sarebbe un trucco. –