2010-08-21 7 views

Répondre

2

Il suffit de regarder la source pour Derived_from, qui est donné exactement dans le même URL que vous pointez vers!

template<class T, class B> struct Derived_from { 
    static void constraints(T* p) { B* pb = p; } 
    Derived_from() { void(*p)(T*) = constraints; } 
}; 

Quel code vous attendez-vous à générer, en plus que dans le constructeur initialiseur unique de Derived_from qui devrait (on l'espère) être facile pour le compilateur d'optimiser l'écart? Et la méthode statique constraints vérifie juste qu'un pointeur sur T peut être correctement affecté à un pointeur sur B - ce qui devrait bien sûr devenir une vérification pure à la compilation que T est en effet dérivé de B, qui est la contrainte que nous désirons.

1

Si la fonction qui effectue ces vérifications effectue uniquement les conversions qui n'ont aucun effet secondaire, l'optimiseur optimisera probablement l'intégralité de ce code et ne générera aucun code pour le corps de la fonction. La seule chose qui reste sera le symbole de la fonction et une instruction de retour. Comme il s'avère (testé avec GCC 4.5.1), même le symbole de la fonction ne doit pas être émis. Le compilateur a optimisé la prise d'adresse, puis observé qu'aucun autre code dans ce fichier n'accède à la fonction, n'émettant pas de code pour cela. Je pense que c'est OK, parce que toute autre unité de traduction qui a besoin de cette définition fournit une définition par elle-même - de sorte qu'ils ne dépendent pas de la compilation d'autres unités de traduction de toute façon.

Notez qu'avec cette méthode, les contrôles ne se déclenchent qu'une fois que vous avez créé un objet Container<T>. Sinon, le constructeur de Derived_from ne sera jamais implicitement instancié et les vérifications ne sont jamais effectuées.

Il existe des moyens d'obtenir ce résultat sans aucun code fictif, comme boost::is_base_of.

Questions connexes