2015-07-14 16 views
5

Sto lottando con i modelli, le funzioni e il binding di C++.Come assegnare una funzione membro come parametro?

Diciamo che la mia classe A è come questo:

class A { 
    void set_enabled_for_item(int item_index, bool enabled); 

    void set_name_for_item(int item_index, std::string name); 

    int item_count(); 
} 

vorrei creare un metodo in A come questo:

template <typename T> 
    void set_for_all_items(T value, ??? func) { 
     auto count = trackCount(); 
     for (auto i = 0; i < count; ++i) { 
      func(i, value); 
     } 
    } 

Così ho potuto chiamarla con una funzione di membro di A in parametro, come questo (o qualcosa del genere):

auto a = new A; 
a->set_for_all_items("Foo Bar", &A::set_name_for_item); 

I tre ??? sarebbe il tipo del secondo parametro. Dato che sono abbastanza nuovo in std :: function, std :: bind e templates, ho provato quello che già sapevo di usare ma ho sempre avuto errori di compilazione.

Quindi come si fa?

risposta

7

La sintassi per una funzione membro standard è Ret (Class::*) (Args...). Nel tuo caso, questo potrebbe essere simile a questa (non testata):

template <typename T, typename Arg> 
void set_for_all_items(T value, void (A::* func) (int, Arg)) { 
    auto count = trackCount(); 
    for (auto i = 0; i < count; ++i) { 
     (this->*func)(i, value); //note the bizarre calling syntax 
    } 
} 

Questo vi permetterà di chiamare con la sintassi che desiderate:

auto a = new A; 
a->set_for_all_items("Foo Bar", &A::set_name_for_item); 

Se si desidera utilizzare std::function, ti è necessario avvolgere la funzione membro con qualcosa che utilizza il parametro oggetto implicito utilizzando un lambda o std::bind o simile.

+0

La soluzione con due tipi indipendenti è migliore per i motivi di conversione: +1 – Angew

+0

Perfetto! La bizzarra sintassi di chiamata era ciò che mi mancava! Grazie per l'aiuto. Accetterò la risposta non appena SO mi consente :) –