Il compilatore genererà il codice per ogni istanza del modello quando si utilizza un modello durante la fase di compilazione. Nel processo di compilazione e collegamento i file .cpp vengono convertiti in puro oggetto o codice macchina che contiene riferimenti o simboli indefiniti poiché i file .h inclusi in main.cpp non hanno ANCORA un'implementazione. Questi sono pronti per essere collegati con un altro file oggetto che definisce un'implementazione per il tuo modello e quindi hai un eseguibile completo a.out.
Tuttavia, poiché i modelli devono essere elaborati nella fase di compilazione per generare il codice per ogni istanza del modello definita, quindi la semplice compilazione di un modello separato dal suo file di intestazione non funzionerà perché vanno sempre di pari passo, proprio per la ragione ogni istanza di modello è letteralmente una nuova classe. In una classe normale è possibile separare .h e .cpp perché .h è un modello di quella classe e .cpp è l'implementazione non elaborata in modo che tutti i file di implementazione possano essere compilati e collegati regolarmente, tuttavia utilizzando i modelli .h è un modello di come la classe non dovrebbe apparire come dovrebbe apparire l'oggetto nel senso che un file .cpp modello non è un'implementazione regolare non elaborata di una classe, è semplicemente un progetto per una classe, quindi qualsiasi implementazione di un file modello .h può '
Pertanto i modelli non vengono mai compilati separatamente e vengono compilati solo laddove si abbia un'istanza concreta in qualche altro file sorgente. Tuttavia, l'istanza concreta deve conoscere l'implementazione del file modello, perché semplicemente modificando il filetypename T
l'uso di un tipo concreto nel file .h non farà il lavoro perché quello che .cpp è lì per collegare, non lo troverò più tardi perché ricordo che i modelli sono astratti e non possono essere compilati, quindi sono costretto per dare l'implementazione in questo momento in modo che io sappia cosa compilare e collegare, e ora che ho l'implementazione, questo viene collegato al file sorgente allegato. Fondamentalmente, nel momento in cui creo un'istanza di un modello, devo creare una classe completamente nuova, e non posso farlo se non so come dovrebbe apparire quella classe quando uso il tipo che fornisco a meno che non lo faccia notare al compilatore di l'implementazione del modello, quindi ora il compilatore può sostituire T
con il mio tipo e creare una classe concreta pronta per essere compilata e collegata.
Per riassumere, i modelli sono schemi per come dovrebbero apparire le classi, le classi sono schemi per come dovrebbe apparire un oggetto. Non riesco a compilare modelli separati dalla loro istanza concreta perché il compilatore compila solo tipi concreti, in altre parole, modelli almeno in C ++, è pura astrazione del linguaggio. Dobbiamo deselezionare i modelli per così dire, e lo facciamo dando loro un tipo concreto da affrontare in modo che l'astrazione dei nostri modelli possa trasformarsi in un normale file di classe e, a sua volta, possa essere compilato normalmente. Separare il file .h modello e il file .cpp modello non ha senso. È privo di senso perché la separazione di .cpp e .h è solo dove il .cpp può essere compilato individualmente e collegato individualmente, con modelli poiché non possiamo compilarli separatamente, perché i modelli sono un'astrazione,
Il significato typename T
viene sostituito durante la fase di compilazione non nella fase di collegamento, quindi se provo a compilare un modello senza T
essere sostituito come un tipo di valore concreto che è completamente privo di significato per il compilatore e di conseguenza non è possibile creare un codice oggetto perché non lo fa sapere cos'è T
.
È tecnicamente possibile creare una sorta di funzionalità che salverà il file template.cpp e cambierà i tipi quando li trova in altre fonti, penso che lo standard abbia una parola chiave export
che ti permetterà di mettere i modelli in un separato file cpp ma non che molti compilatori lo implementino.
Solo una nota a margine, quando si effettuano specializzazioni per una classe modello, è possibile separare l'intestazione dall'implementazione perché una specializzazione per definizione significa che sono specializzato per un tipo concreto che può essere compilato e collegato individualmente.