2010-09-08 5 views

Répondre

9

L'instanciation différée est lorsque le modèle n'est pas instancié jusqu'à ce que l'entité correspondante soit utilisée pour la première fois. Par exemple, vous avez une fonction templated:

template<int Size> 
void YourFunction() 
{ 
    //does something 
} 

paramètre Size peut avoir une valeur possible que int peut avoir. Avez-vous automatiquement la fonction template instanciée pour toutes les valeurs possibles de Size? Non, le modèle est seulement instancié pour les valeurs qui sont effectivement utilisées comme paramètre lorsque l'appel de fonction apparaît d'abord dans le code:

YourFunction<100>(); //instantiated for 100 
+1

+1. J'aime le suspense que vous ajoutez en posant des questions ;-) –

+0

La raison pour laquelle ceci est important: imaginez une ligne 'const int nombre = 100/Size;'. Il ne devrait pas générer d'erreur jusqu'à ce que quelqu'un essaie d'utiliser 'YourFunction <0>'. – MSalters

+0

@MSalters: Oui, ça aussi. Mais imaginez aussi que le compilateur essaie d'instancier cette fonction pour chaque valeur possible de 'int' - ce serait beaucoup de données intermédiaires. – sharptooth

2

Je n'ai entendu des gens utilisent le terme « instanciation différée » pour désigner la situation où une définition de membre de la classe est instanciée seulement si elle est utilisée

template<typename T> 
struct A { 
    void f() { 
    T a; // invalid if T is void 
    } 
}; 

A<void> a; // valid! 

Dans ce cas, A<void> est instancié implicitement parce que le compilateur a besoin de connaître sa taille (formellement, le type de classe doit être complète, donc une instanciation est déclenché). Mais l'instanciation de ses définitions de membre sont différées jusqu'à ce qu'elles soient réellement utilisées. Cela ne vaut pas seulement pour les fonctions membres, mais aussi aux membres de données statiques et classes imbriquées

struct Print { 
    Print() { std::cout << "hello!"; } 
}; 

template<typename T> 
struct A { 
    static Print print; 
}; 

template<typename T> 
Print A<T>::print; 

Maintenant, même si vous implicitement instancier A<T> le message ne sera pas imprimé jusqu'à ce que vous faites référence explicitement à A<T>::print et utilisation il . L'instanciation explicite ne différer instanciation des définitions membres - donc ce qui suit toujours imprimer le message

template struct A<void>; 

Il y a une astuce pour déclencher instanciation des définitions membres pour instanciations implicites si: Se référer à eux dans certaines parties de la déclaration d'une classe «membre, comme dans le modèle de classe changé suivant

template<typename T, T&> struct useit { }; 

template<typename T> 
struct A { 
    static Print print; 
    typedef useit<Print, print> useit_type; 
}; 

maintenant, si A<T> est implicitement instanciée le message est imprimé, parce que la déclaration typedef fait référence.

Questions connexes