2009-12-10 4 views
21

J'ai un code qui fonctionne à 100% pour le cas d'utilisation que j'ai. Je me demande simplement si quelqu'un peut expliquer comment et pourquoi cela fonctionne.Passer un pointeur sur une fonction membre en tant qu'argument de modèle. Pourquoi cela fonctionne-t-il?

J'ai une classe de modèle qui se trouve entre un code qui gère le threading et la communication réseau et l'utilisateur de la bibliothèque pour transmettre les données reçues du serveur à l'utilisateur.

template <class Bar, 
      class Baz, 
      class BazReturnType, 
      void (Bar::*BarSetterFunction)(const BazReturnType &), 
      BazReturnType (Baz::*BazGetterFunction)(void) const> 
class Foo 
{ 
    Foo(Bar *bar) 
     : m_bar(bar) 
    { 
    } 

    void FooMemberFunction(const Baz *baz) 
    { 
     boost::bind(BarSetterFunction, m_bar, 
        boost::bind(BazGetterFunction, baz)())(); 
    } 

    Bar *m_bar; 
}; 

Ce modèle est instancié et utilisé dans la bibliothèque en fonction des types de Bar et Baz comme si:

typedef Foo<MyBar, 
      MyBaz, 
      ReturnTypeFromBazGetterFunction, 
      &MyBar::ActualSetterFunction, 
      &MyBaz::ActualGetterFunction > 
    MyFoo; 

MyBar *bar = new MyBar; 
MyBaz *baz = new MyBaz; 
MyFoo *f = new MyFoo(bar); 
f->FooMemberFunction(baz); 

tout cela fonctionne et boost :: bind appelle les fonctions getter/setter pour passer les données autour de l'endroit où il doit aller. Comment et pourquoi le passage de pointeurs vers des fonctions membres en tant qu'argument de modèle fonctionne-t-il dans ce cas?


En réponse aux commentaires, je ne l'avais pas réalisé que des pointeurs vers les fonctions membres étaient des arguments de modèle valides. Ce n'est pas quelque chose que j'avais vu "dans la nature" avant. J'ai essayé et ça a marché, mais je ne m'y attendais pas.

+1

Je ne suis pas sûr de comprendre exactement ce que vous demandez. Un pointeur vers un membre est l'un des types autorisés de paramètre de modèle non-type. Cherchez-vous simplement une référence à cela dans la norme? 14.1/4 [templ.param] –

Répondre

34

Je pense qu'il ya une meilleure explication pourquoi il est possible de le faire que « parce que la norme le dit »:

La raison pour laquelle cela fonctionne est parce que des pointeurs à-membres sont des valeurs constantes connues au moment de la compilation (pointeur vers membre est effectivement un décalage d'un membre depuis le début d'une classe). Ainsi, ils peuvent être utilisés comme paramètres de modèles, tout comme n'importe quelle autre constante entière. D'autre part, les pointeurs normaux ne sont pas des constantes de temps de compilation, car ils dépendent de la disposition de la mémoire qui n'existe qu'au moment de l'exécution. Ils ne peuvent pas être des arguments de modèle.

+9

+1 Je vous salue pour votre première phrase. – Mehrdad

2

Lorsque vous posez une question dans le sens de "pourquoi quelque chose fonctionne?", Cela implique que le fait que cela fonctionne vous surprend quelque peu. Il est impossible de répondre à la question sauf si vous expliquez pourquoi vous trouvez cela surprenant.

Pourquoi cela fonctionne-t-il? Parce que la spécification du langage dit explicitement qu'elle fonctionnera. Il n'y a pas d'autre réponse, jusqu'à ce que vous expliquiez vos préoccupations plus en détail.

+0

Je suppose que "parce que la spécification du langage le dit" est la réponse. Je n'avais pas réalisé que les pointeurs vers les fonctions membres étaient des arguments de gabarit valides selon la norme. –

Questions connexes