/ / Quando viene verificato un tipo di istanza del modello C ++? - c ++, modelli

Quando viene controllato il tipo di istanza del template C ++? - c ++, modelli

Durante la compilazione di C ++, gcc e clang sembra posticipare il controllo dei tipi di istanze dei template fino a dopo che tutte le dichiarazioni del programma sono state elaborate. È garantito nella lingua?

Per elaborare, posso mantenere un tipo incompleto nel punto in cui è definito un modello o è necessaria un'istanza del modello, purché completi il ​​tipo da qualche parte più avanti nel programma:

class A;
class B;

extern A* pa;

// 1. template definition
template<typename T>
T* f() { return static_cast<T*>(pa); }

// 2. template instantiation
B* test() { return f<B>(); }

// 3. completing types
class A { };
class B : public A { };

Si noti che le definizioni di A e B sono necessarie per digitare controllare l'istanza del modello (per rendere valido lo static_cast). Se si omette il passaggio 3, il passaggio 2 non verrà più compilato.

Nell'organizzazione dei miei header, posso contare che questo ordine sarà accettato da qualsiasi compilatore C ++ standard?

risposte:

5 per risposta № 1

La regola è chiamata "ricerca del nome in due fasi".

I nomi, che non dipendono dai parametri del modello, vengono controllati e controllati alla definizione e il nomi dipendenti sono controllati nel punto di istanziazione.

Per il tuo esempio, c'è un dettaglio importante: la fine dell'unità di traduzione è anche considerata un punto di istanziazione per i modelli di funzione:

C ++ 14 N4140 14.6.4.1 [temp.point] P8:

Una specializzazione per un modello di funzione, amodello di funzione membro, o di una funzione membro o statica membro di dati di un modello di classe può avere più punti di istanze all'interno di un'unità di traduzione, e oltre ai punti di istanziazione sopra descritti, per ogni specializzazione che ha un punto di istanziazione all'interno dell'unità di traduzione, anche la fine dell'unità di traduzione è considerata un punto di istanziazione.

Pertanto, sebbene il tipo sia incompleto al punto "2", dove avviene l'istanziazione esplicita, è completo alla fine del file, il che rende legittima l'istanziazione del template.

Nota: Il compilatore Microsoft non implementa questa regolain pieno, violando lo standard. Nel compilatore Microsoft, tutta la ricerca avviene nel punto di istanziazione (quindi anche l'esempio dovrebbe funzionare, ma non ho accesso a MSVC per verificare) Altri compilatori importanti implementano correttamente questa regola.