Übergeben eines Zeigers auf eine Elementfunktion als Vorlage Argument. Warum funktioniert das?

StackOverflow https://stackoverflow.com/questions/1882740

Frage

Ich habe einige Code, dass 100% für den Anwendungsfall arbeitet die ich habe. Ich frage mich nur, ob jemand kann erklären, wie und warum es funktioniert.

Ich habe eine Template-Klasse, die zwischen einigen Code sitzt, die und die Netzwerkkommunikation und der Bibliothek-Handles Einfädeln Daten von dem Server zu dem Benutzer empfangen zu ü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 ruft die Getter / Setter-Funktionen, die Daten zu übergeben um, wo es gehen muss. Wie und warum tut Zeiger auf Elementfunktionen als Template-Argument wie in diesem Fall Arbeit vorbei?


Als Reaktion auf die Kommentare, ich hatte nicht bemerkt, dass Zeiger auf Elementfunktionen gültige Vorlage Argumente waren. Es ist nicht etwas, das ich „in the wild“ gesehen hatte. Ich versuchte es und es funktionierte, aber ich hatte erwartet, es nicht zu tun.

War es hilfreich?

Lösung

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

Der Grund, es funktioniert, weil Zeiger-to-Mitglieder sind konstante Werte zum Zeitpunkt der Kompilierung bekannt (Zeiger-to-User ist effektiv ein Offset eines Mitglieds aus dem Beginn einer Klasse). So können sie als Parameter von Vorlagen verwendet werden, ebenso wie jede andere ganze Zahl konstant sein kann.

Auf der anderen Seite, normale Zeiger werden nicht Zeitkonstanten kompilieren, weil sie auf Speicherlayout abhängen, die erst zur Laufzeit vorhanden ist. Sie können nicht Vorlage Argument sein.

Andere Tipps

Wenn Sie eine Frage nach dem Vorbild der fragen: „Warum etwas funktioniert?“, Bedeutet dies, dass die Tatsache, dass es funktioniert Sie irgendwie überraschend. Es ist unmöglich, die Frage zu beantworten, wenn Sie erklären, warum Sie finden es überraschend.

Warum es funktioniert? Da die Sprachspezifikation sagt ausdrücklich, dass es funktionieren wird. Es gibt keine andere Antwort, bis Sie Ihre Anliegen näher erläutern.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top