2012-09-13 26 views
6

Say mam te 3 różne funkcje, które mogą chcę zwrócić się do:Używanie std :: funkcja jako delegat w C++ 11

float test1(int a, int b) { 
    return 7.0f; 
} 

struct TestClass { 
    float test2(int a, int b) { 
     return 5.0f; 
    } 
}; 

struct TestClass2 { 
    float test3(int a, int b) { 
     return 3.0f; 
    } 
}; 

Zauważ, jak wszystkie trzy używać tych samych argumentów i wartości zwracanej. Chcę wykreślić, czy jest to funkcja członkowska i do której klasy należy. Chcę typu delegata, który może odnosić się do dowolnej z tych 3 funkcji w zależności tylko od tego, jak został zainicjowany.

Oto moja pierwsza próba:

typedef std::function<float(int, int)> MyDelegate; // is this right? 

int main() { 
    TestClass obj; 
    TestClass2 obj2; 

    MyDelegate a = test1; 
    MyDelegate b = std::bind(std::mem_fn(&TestClass::test2), obj); // is this right? 
    MyDelegate c = std::bind(std::mem_fn(&TestClass2::test3), obj2); // is this right? 

    return 0; 
} 

Chodzi o to, chcę też zapisać „ten” wskaźnik wewnątrz owijki też. W ten sposób jest to w pełni funkcjonalny delegat. Na przykład wywołanie "b (x, y)" powinno być jak wywołanie obj.test2(x, y).

Po prostu nie mogę nawet zmusić go do kompilacji, prawdopodobnie nie całkiem to rozumiem. Jestem trochę nowy w tych bibliotekach i błędy w VS2012 są katastrofalnie nieprzydatne. Każda pomoc będzie doceniona.

+0

możliwy duplikat wywołań zwrotnych w stylu C++ 11? (Http://stackoverflow.com/questions/12338695/c11-styled-callbacks) – Klaim

Odpowiedz

9

Musisz powiedzieć std::bind, co zrobić z innymi parametrami funkcji. W celu dokonania połączenia b(x, y) delegata x i y do dwóch pierwotnych parametrów funkcyjnych trzeba używać zastępczych z std::placeholders nazw:

std::bind(&TestClass::test2, obj, std::placeholders::_1, std::placeholders::_2); 

i tam również nie ma potrzeby std::mem_fn (to działa, chociaż), ponieważ std::bind już poprawnie obsługuje funkcje składowe (sprawiając, że domyślny argument this jest jawnym pierwszym argumentem, takim jak std::mem_fn).

3

Trzeba dostarczyć 2 argumenty do std :: wiązania lub dostarczenie zastępcze w celu zapewnienia im później:

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, 1, 2); 
c(); //returns result 

LUB

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, std::placeholders::_1, std::placeholders::_2); 
c(1, 2); //returns result 

Więcej informacji o std :: wiążą się here.

2

Korzystanie Visual C kompilator ++ (CTP 2012) i szpiegował jak zrobili std :: funkcję i deliviered moje własne rozwiązanie do obsługi funkcji składowych

użycie wygląda następująco: http://ideone.com/v5zfDn

class Window 
{ 
public: 
    void Show(int number) const 
    { 
     //... 
    } 

    void ShowDynamic(int number) volatile 
    { 
     //... 
    } 
}; 

void ShowWindows(int param) 
{ 
    //... 
} 

int main() 
{ 
    Window window; 

    typedef mezutils::Delegate< void(int) > Notifier; 
    Notifier notifier; 

    notifier = &ShowWindows; 
    notifier(0); 

    notifier = Notifier(&window, &Window::Show); 
    notifier(1); 

    notifier = [](int x) { /*...*/ }; 
    notifier(2); 

    void (*funpc)(int) = func; 
    notifier = funpc; 
    notifier(3); 

    notifier = [](int arg) { printf("asd %d\r\n",arg); }; 
    notifier(4); 
    return 0; 
} 

klasy delegat wygląd jak: http://ideone.com/DebQgR

oczywiście jest to prototyp wykonany dla zabawy, ale podoba mi się to, bo to jasne

Powiązane problemy