Passando un puntatore a una funzione di membro come un argomento di template. Perché questo lavoro?

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

Domanda

Ho un codice che il 100% lavora per il caso d'uso che ho. Mi chiedo solo se qualcuno può spiegare come e perché funziona.

Ho una classe template che si trova tra un po 'di codice che gestisce la filettatura e la comunicazione di rete e l'utente biblioteca per passare i dati ricevuti dal server per l'utente.

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

Questo modello viene creata un'istanza e utilizzato nella biblioteca a seconda delle tipologie di Bar e Baz in questo modo:

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

Questa tutte le opere e boost :: bind chiama le funzioni getter / setter per passare i dati intorno a dove deve andare. Come e perché lo fa passare puntatori a funzioni membro come un argomento di un template come in questo caso il lavoro?


In risposta ai commenti, non avevo capito che i puntatori a funzioni membro sono stati gli argomenti di modello valido. Non è qualcosa che avevo visto "in the wild" prima. L'ho provato e ha funzionato, ma non mi aspettavo che.

È stato utile?

Soluzione

Credo che ci sia una spiegazione migliore perché è possibile farlo più "perché la norma dice così":

Il motivo che funziona è perché puntatori-a-membri sono valori costanti noti al momento della compilazione (puntatore-a-membro è effettivamente un offset di un membro dall'inizio di una classe). Così essi possono essere utilizzati come parametri di modelli, così come qualsiasi altra costante intera può essere.

D'altra parte, i puntatori normali non compilare costanti di tempo, in quanto dipendono layout della memoria che esiste solo in fase di esecuzione. Essi non possono essere argomenti di template.

Altri suggerimenti

Quando si chiede una domanda sulla falsariga di "perché qualcosa opere?", Ciò implica che il fatto che funziona sia in qualche modo sorprendente per voi. E 'impossibile rispondere alla domanda se non si spiegare perché si trovano sorprendente.

Perché funziona? Poiché la specifica del linguaggio dice esplicitamente che essa si adopera. Non c'è altra risposta, fino a quando non spiegare le vostre preoccupazioni in modo più dettagliato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top