2009-12-10 3 views
21

Ich habe einen Code, der 100% für den Anwendungsfall funktioniert, den ich habe. Ich frage mich nur, ob jemand erklären kann, wie und warum es funktioniert.Übergabe eines Zeigers an eine Elementfunktion als Vorlageargument. Warum funktioniert das?

Ich habe eine Vorlage-Klasse, die zwischen einigen Code, der Threading und Netzwerkkommunikation behandelt und der Bibliotheksbenutzer zum Übergeben von Daten vom Server an den Benutzer übergeben.

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; 
}; 

Diese Vorlage wird instanziiert und in der Bibliothek in Abhängigkeit von der Art der Bar und Baz wie so verwendet:

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); 

Das alles funktioniert und boost :: bind die Getter/Setter-Funktionen aufruft passieren die Daten dort, wo es hingehört. Wie und warum funktioniert das Übergeben von Zeigern an Member als Template-Argument, wie in diesem Fall?


In Reaktion auf die Kommentare, hatte erkannt, ich nicht, dass Zeiger auf Elementfunktionen gültige Vorlage Argumente waren. Es ist nicht etwas, das ich zuvor "in der Wildnis" gesehen habe. Ich habe es versucht und es hat funktioniert, aber ich habe es nicht erwartet.

+1

Ich bin mir nicht sicher, ob ich genau verstehe, was Sie fragen. Ein Zeiger auf Element ist einer der zulässigen Typen von Nicht-Typ-Vorlagenparametern. Suchen Sie im Standard nach einer Referenz? 14.1/4 [templ.param] –

Antwort

34

Ich denke, es ist eine bessere Erklärung dafür, warum es möglich ist, so zu tun, als „weil der Standard sagt so“:

Der Grund, es funktioniert, weil Zeiger-to-Mitglieder konstante Werte sind zum Zeitpunkt der Kompilierung bekannt (pointer-to-member ist effektiv ein Offset eines Members vom Anfang einer Klasse). Daher können sie als Parameter für Templates verwendet werden, genau wie jede andere Integer-Konstante.

Auf der anderen Seite sind normale Zeiger keine Kompilierzeitkonstanten, da sie vom Speicherlayout abhängen, das nur zur Laufzeit existiert. Sie können keine Vorlagenargumente sein.

+9

+1 Ich grüße Sie für Ihren ersten Satz. – Mehrdad

2

Wenn Sie eine Frage im Sinne von "Warum etwas funktioniert?", Bedeutet es, dass die Tatsache, dass es funktioniert, irgendwie überraschend für Sie ist. Es ist unmöglich, die Frage zu beantworten, es sei denn, Sie erklären , warum Sie es überraschend finden.

Warum funktioniert es? Weil die Sprachspezifikation ausdrücklich sagt, dass es funktionieren soll. Es gibt keine andere Antwort, bis Sie Ihre Bedenken ausführlicher erklären.

+0

Ich denke, "weil die Sprachspezifikation so sagt" ist die Antwort. Ich hatte nicht erkannt, dass Zeiger auf Member-Funktionen gültige Template-Argumente nach dem Standard waren. –

Verwandte Themen