2015-07-14 26 views
5

Mam problemy z szablonami C++, funkcjami i powiązaniami.Jak ustawić funkcję składową jako parametr?

Powiedzmy moja klasa A jest tak:

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

Chciałbym utworzyć metodę w A tak:

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

Więc mogę nazwać to z funkcją członkiem w parametrze, jak to (lub coś podobnego):

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

Trzy ??? byłby typem drugiego parametru. Ponieważ jestem całkiem nowym użytkownikiem std :: function, std :: bind i templates, próbowałem tego, co już wiedziałem, ale zawsze miałem błędy kompilacji.

Jak to zrobić?

Odpowiedz

7

Składnia standardowej funkcji składowej to Ret (Class::*) (Args...). W twoim przypadku może to wyglądać mniej więcej tak (niesprawdzone):

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

To pozwoli Ci zadzwonić ze składnią pragnienie:

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

Jeśli chcesz użyć std::function, będziesz trzeba zawijać swoją funkcję członkowską za pomocą czegoś, co przyjmuje parametr obiektu niejawnego za pomocą znaku lambda lub std::bind lub podobnego.

+0

Twoje rozwiązanie z dwoma niezależnymi typami jest lepsze z powodów konwersji: +1 – Angew

+0

Idealne! Dziwna składnia wywołania była tym, czego mi brakowało! Dziękuję za pomoc. Przyjmuję odpowiedź tak szybko, jak SO pozwoli mi :) –