I modelli C ++ sono solo una specie di macro glorificate?


27

Da diversi confronti tra modelli C ++ e generici C # / Java come questo-

/programming/31693/what-are-the-differences-between-generics-in-c-and-java-and-templates-in-c/31929#31929

Ho capito che i modelli C ++ sono implementati da una sorta di pre-elaborazione (sostituzione del testo normale prima dell'analisi), non compilazione. Perché il controllo del tipo nei modelli C ++ assomiglia alle macro C. Voglio dire, se ci sono alcuni errori, sono errori dal codice generato dopo l'elaborazione dei blocchi di codice modello, non dai modelli stessi. In altre parole, sono solo una specie di versione superiore di macro in C.

Poi ho trovato alcuni altri fatti a sostegno di questo-

  • Ho pensato, se i modelli C ++ sono implementati tramite preelaborazione, ci saranno problemi con il collegamento dinamico (usando .dll). E una rapida ricerca su Google ha supportato questo.

  • Un altro punto è che le costanti intere possono essere passate come argomenti ai template. E supporta anche una sorta di ricorsione. Ma questa ricorsione non si trova nel codice assembly / machine compilato. La cosa ricorsione è gestita in tempo di compilazione generando una funzione per ogni chiamata ricorsiva e quindi avendo un binario eseguibile più grande ma più veloce.

Sebbene diversamente dalle macro C, ha alcune abilità superiori. Ma il modello C ++ non è implementato con una sorta di pre-elaborazione? Come viene implementato in diversi compilatori C ++?


19
No. I modelli C ++ sono compilati.
Edward Strange

2
Qual è la tua definizione di "preelaborazione"? E di "compilare"? Una definizione sufficientemente ampia di "preelaborazione" potrebbe includere tutto ciò che fa un compilatore; dopo tutto, un compilatore elabora davvero il sorgente prima che venga eseguito, no?
James McNellis,

@James McNellis IMHO se riesci a differenziare la preelaborazione da tutte le altre cose fatte per la compilazione, è sufficiente capire la mia domanda. Per chiarire preprocessor- it.wikipedia.org/wiki/Preprocessor#Lexical_preprocessors
Gulshan

6
Se ti riferisci a quella forma di preelaborazione, allora no, i modelli C ++ non sono assolutamente solo una sorta di macro glorificata.
James McNellis,

1
Il linguaggio dei template è attualmente in fase di completamento, quindi sono molto più che macro migliorate.
davidk01,

Risposte:


9

I modelli C ++ sono una sorta di macro Lisp (o anche più, Scheme) ridotte al minimo. È un linguaggio completo di Turing che valuta in tempo di compilazione, ma è fortemente limitato in quanto non vi è accesso da quel linguaggio all'ambiente C ++ sottostante. Quindi, sì, i modelli C ++ possono essere visti come una qualche forma di pre-elaborazione, con un'interazione molto limitata con il codice generato.


2
"ma è fortemente limitato in quanto non vi è alcun accesso da quella lingua all'ambiente C ++ sottostante." -- Cosa significa? Ho provato ad analizzare questa affermazione, ma non ci sono riuscito.
quant_dev,

2
Uhm, in realtà ... github.com/kmichel/bf0x
Anton Golov,

3
@ SK-logic: A parte questo, C ++ 11 è C ++, a meno che tu non tratti (pedanticamente) versioni diverse della stessa lingua come lingue diverse.
Jon Purdy,

3
@Jon Purdy, C ++ 11 non esisteva (ufficialmente) al momento di questa risposta. Oggi un esempio sarebbe stato più complicato, come la decomposizione di una struttura di dati, l'utilizzo di una funzione di libreria, ecc.
Logica SK

1
@ SK-logic: ti capita di conoscere l'implementazione di C ++ con macro simili a Lisp? Mi sto stancando delle limitazioni del modello. Un esempio di linguaggio di sintassi in stile C ++ con un potente sistema macro in Haxe: haxe.org/manual/macros . (Non mi aiuta perché uso C ++ per il suo scopo: programmare microcontrollori a 8 bit; ci sono lingue migliori per qualsiasi altra cosa).
falco

41

Probabilmente la più grande differenza è che le macro C vengono espanse nella fase di preelaborazione, prima che venga eseguita qualsiasi altra compilazione, mentre i modelli C ++ fanno parte della compilazione. Ciò significa che, tra le altre cose, i modelli C ++ sono consapevoli del tipo e con ambito e non sono semplici sostituzioni testuali. Possono compilare funzioni reali e quindi evitare la maggior parte dei problemi delle macro. Essere consapevoli del tipo significa che possono essere generici o specializzati: ad esempio, è facile fornire una swapfunzione modello e specializzazioni facili da scrivere che funzionano bene anche se gli oggetti gestiscono la memoria dell'heap.

Pertanto: i modelli C ++ non sono preelaborati nello stesso senso delle macro, non sono un tipo di macro C ed è impossibile utilizzare le macro C per duplicare ciò che fanno i modelli.

I modelli vivono in file di intestazione, non in librerie collegate, vero, ma se stai fornendo un .dll presumibilmente stai fornendo anche un file di intestazione da usare.


12
Non hanno bisogno di vivere nel file di intestazione (questa è solo la tecnica più semplice per usarli). È possibile definirli in un file di origine e forzare manualmente l'istanza del modello nel file di origine (unità di compilazione). Il collegamento raccoglierà quindi le istanze normalmente (questa è una tecnica per limitare i modelli a tipi specifici e non consentire tutti i tipi generici).
Martin York,

@Martin: Non sono sicuro che questa tecnica (mentre supportata) sia effettivamente esplicitamente supportata dallo standard. Altrimenti tutti i compilatori avrebbero exportgià implementato. Lo so che in qualche modo funziona per le funzioni, ma dubito che funzioni per le classi: come faresti a conoscerne le dimensioni?
Matthieu M.,

@Matthieu M: non ha nulla a che fare con la parola chiave export. Gestisce l'istanza del modello "esplicito" ed è ben definita nello standard.
Martin York,

2
@Matthieu M .: Se il compilatore conosce la firma di una funzione e il linker riesce a trovare un'implementazione, va tutto bene. Ciò vale indipendentemente dal fatto che la funzione sia o meno una funzione modello. In pratica, vivono generalmente in file header, perché forzare istanze specifiche è in genere più lavoro di quanto valga la pena, ma Martin ha ragione nel notare l'alternativa.
David Thornley,

So che funziona sicuramente per funzioni specializzate. Tuttavia, sono anche abbastanza sicuro che non funzioni per le lezioni, il che era il mio punto. Penso che funzioni anche con metodi di classi specializzate, ma non so se questo è standard.
Matthieu M.,

5

Importa come vengono implementati? I primi compilatori C ++ erano solo pre-processori che fornivano il codice al compilatore ac, non significa che C ++ sia solo una macro glorificata.

I modelli eliminano la necessità di macro fornendo un modo più sicuro, più efficiente e specializzabile (anche se non credo sia una parola vera) di implementare il codice per più tipi.

Esistono diversi modi per eseguire il codice del tipo di modello in c, nessuno dei quali è molto utile una volta superati i tipi semplici.


Non ho detto che C ++ sia una macro glorificata. Ammiro molto il C ++. Solo essere curioso.
Gulshan,

2
@Gulshan: No, non hai detto nulla al riguardo. Tuttavia, è così che hanno funzionato i primi compilatori C ++ (tranne per il fatto che CFront era una sorta di compilatore anziché solo un preprocessore macro), e le tue dichiarazioni sui modelli C ++ sono applicabili al primo C ++ stesso.
David Thornley, l'11

CFront ha compilato C ++ in C. La linea tra il preprocessore e il compilatore è chiaramente definita: un compilatore tenta di capire il suo input - tramite analisi, costruzione AST, ecc. - mentre un preprocessore non lo fa - ad esempio, usando solo la sostituzione testuale o token.
Jon Purdy,

1
Penso che ciò che David intendesse sia che esiste un sottoinsieme di C ++ e che i modelli possono essere considerati come una sorta di macro che viene utilizzata per un programma generale in questo sottoinsieme, che può quindi essere compilata come ulteriore fase separata.
Giorgio,

5

Ci sono alcune differenze; ad esempio, i modelli possono essere utilizzati per creare un'istanza di un sovraccarico della funzione quando necessario, mentre con le macro dovresti espandere la macro una volta per ogni possibile sovraccarico per renderla visibile al compilatore, quindi finiresti con un sacco di codice inutilizzato.

Un'altra differenza è che i modelli onorano gli spazi dei nomi.


2

I modelli IMHO, C ++ e Macro C avevano lo scopo di risolvere due problemi completamente diversi. La libreria di modelli standard C ++ originale era un meccanismo per disaccoppiare in modo pulito le classi di container (array, elenchi collegati, ecc.) Dalle funzioni generiche comunemente applicate ad essi (come l'ordinamento e la concatenazione). Avere rappresentazioni astratte di algoritmi efficienti e strutture di dati porta a un codice più espressivo perché c'erano molte meno congetture su come implementare al meglio una funzione che lavora su un particolare pezzo di dati. Le macro C erano molto più in linea con ciò che si vedrebbe in genere nelle macro Lisp, in quanto fornivano un mezzo per "estendere" la lingua con il codice incorporato. La cosa interessante è che la libreria standard C ++ ha esteso la funzionalità dei modelli per coprire la stragrande maggioranza di ciò che usiamo per #define in C.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.