Carichi di librerie C++, incluso lo standard, consentono di adattare gli oggetti per l'utilizzo nelle librerie. La scelta è spesso tra una funzione membro o una funzione libera nello stesso spazio dei nomi.Meccanica dell'estensione tramite funzioni libere o funzioni membro
Mi piacerebbe conoscere la meccanica e costruisce il codice libreria utilizzato per inviare una chiamata che chiamerà una di queste funzioni di "estensione", so che questa decisione deve aver luogo durante la compilazione e prevede modelli. Il seguente psuedocode di runtime non è possibile/non-sense, le ragioni sono fuori dallo scopo di questa domanda.
if Class A has member function with signature FunctionSignature
choose &A.functionSignature(...)
else if NamespaceOfClassA has free function freeFunctionSignature
choose freeFunctionSignature(...)
else
throw "no valid extension function was provided"
Il codice sopra appare come il codice di runtime: /. Quindi, come fa la biblioteca a capire lo spazio dei nomi in cui si trova una classe, come rileva le tre condizioni, quali altre insidie ci sono che devono essere evitate.
La motivazione per la mia domanda è per me essere in grado di trovare i blocchi di invio nelle librerie e di essere in grado di utilizzare i costrutti nel mio codice. Quindi, risposte dettagliate aiuteranno.
!! PER VINCERE BOUNTY !!
Ok così secondo la risposta di Steve (e dei commenti) ADL e SFINAE sono i costrutti chiave per il cablaggio del dispatch in fase di compilazione. Ho la testa attorno ADL (in primis) e SFINAE (ancora in sordina). Ma non so come si orchestrano insieme nel modo in cui penso che dovrebbero.
Voglio vedere un esempio illustrativo di come questi due costrutti possono essere messi insieme in modo che una libreria possa scegliere in fase di compilazione se chiamare una funzione membro fornita dall'utente in un oggetto o una funzione libera fornita dall'utente fornita nel spazio dei nomi dello stesso oggetto. Questo dovrebbe essere fatto solo usando i due costrutti sopra, nessun invio runtime di alcun tipo.
Diciamo che l'oggetto in questione è chiamato NS::Car
e questo oggetto deve fornire il comportamento di MoveForward(int units)
, come funzione membro di c. Se il comportamento deve essere rilevato dal namespace dell'oggetto, probabilmente assomiglia allo MoveForward(const Car & car_, int units)
. Definiamo la funzione che desidera inviare mover(NS::direction d, const NS::vehicle & v_)
, dove direction è un enum e v_ è una classe base di NS::car
.
Non è possibile eseguire l'override dell'operatore '' nella classe per l'output in un flusso. Un operatore membro deve avere la classe a sinistra dell'operatore, non a destra. Inoltre, la ricerca dei nomi fa parte del compilatore, non della libreria, e coinvolgerà i modelli solo se è coinvolta una classe template o una funzione template. Se ti stai chiedendo come è fatta la ricerca del nome, ti preghiamo di chiarire la tua domanda. Altrimenti, non so cosa stai chiedendo. –
@david Sì, ho sbagliato su 'operator <<' Ho rimosso l'esempio, ma qualcuno stava modificando la mia domanda e ha sovrascritto la rimozione: D –