I (vagamente) noto che un modello non viene istanziato se è nonutilizzato. Ad esempio, il codice seguente verrà compilato correttamente anche se T::type
non ha senso quando T = int
.L'impatto del virtuale sull'utilizzo del modello membro della classe
template<typename T>
struct A
{
void f() { using type = typename T::type; }
};
A<int> a; //ok
Compila perché f()
non è usato, quindi non viene creata un'istanza — così la validità di T::type
rimane incontrollato. Non importa se qualche altra membro funzione g()
chiama f()
.
template<typename T>
struct A
{
void f() { using type = typename T::type; }
void g() { f(); } //Is f() still unused?
};
A<int> a; //ok
Questo anche compile fines. Ma qui mi rendo conto della vaghezza nella mia comprensione della definizione di "use". Chiedo:
f()
è ancora inutilizzato? Come esattamente?
Posso chiaramente vederlo utilizzato all'interno di g()
. Ma poi ho pensato che dal momento che g()
non viene utilizzato, non viene utilizzato anche f()
, dal punto di vista dell'istanziazione. Sembra abbastanza ragionevole. finora.
Tuttavia, se aggiungo virtual
parola chiave per g()
, non compilare:
template<typename T>
struct A
{
void f() { using type = typename T::type; }
virtual void g() { f(); } //Now f() is used? How exactly?
};
A<int> a; //error
Essa si traduce in compilation error perché ora tenta di creare un'istanza f()
. Non capisco questo comportamento.
Qualcuno potrebbe spiegarlo? Soprattutto l'impatto della parola chiave virtual
sulla definizione di "uso" del modello membro della classe.
Se ricordo correttamente, 'virtual' forza l'istanziazione della funzione membro perché è praticamente impossibile valutare staticamente se questa funzione verrà utilizzata o meno. In pratica, stai chiedendo di creare una v-table piena di puntatori alle funzioni ... quindi la funzione deve esistere in modo tale che possiamo prendere un puntatore. –
Il modello di struct viene istanziato solo quando lo si utilizza. È o l'intera struttura o nulla. Non ha nulla a che fare con gof. – Sarien
@Sarien: lo fa, le funzioni membro di una classe template vengono istanziate solo se usate ODR. –