2012-05-11 27 views
10

Oto kod:std :: funkcja -> funkcja wskaźnik

#include <functional> 
using namespace std::tr1; 

typedef void(*fp)(void); 

void foo(void) 
{ 

} 

void f(fp) 
{ 

} 

int main() 
{ 
    function<void(void)> fun = foo; 
    f(fun); // error 
    f(foo); // ok 
} 

Pierwotnie muszę zrobić wskaźnik funkcji z non-statycznej metody klasy, bo trzeba zapisać dane między powołaniach funkcyjnych. Próbowałem std::tr1::bind i boost::bind, ale zwracają obiekt funkcjonalny, a nie wskaźnik, który, jak widzę, nie może zostać "wyrzucony" do czystego wskaźnika funkcyjnego. Podczas gdy podpis funkcji (SetupIterateCabinet) wymaga dokładnie czystego wskaźnika funkcyjnego.

Potrzebuję porady, jak rozwiązać problem. Dziękuję Ci.

Odpowiedz

7

pan znacznie uproszczony swój prawdziwy problem i okazało się pytanie o XY problem. Wróćmy do pytania o prawdziwe: SetupIterateCabinet z niestatyczną funkcją składową jako callbackiem.

Biorąc pod uwagę pewną klasę:

class MyClass 
{ 
public: 
    UINT MyCallback(UINT Notification, UINT_PTR Param1, UINT_PTR Param2) 
    { 
     /* impl */ 
    } 
}; 

Aby korzystać MyClass::MyCallback jako trzeci argument SetupIterateCabinet, trzeba zdać MyClass* dla Context argumentu i użyć zwykłego funkcję podkładkę do podjęcia że Context argument i zrobienia Właściwie to:

UINT MyClassCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2) 
{ 
    return static_cast<MyClass*>(Context)->MyCallback(Notification, Param1, Param2); 
} 

int main() 
{ 
    MyClass mc; 
    SetupIterateCabinet(_T("some path"), 0, MyClassCallback, &mc); 
} 
+0

To działa, dziękuję! – fogbit

8

Nie można przekonwertować obiektu std::function na wskaźnik funkcji (można zrobić odwrotnie). Powinieneś użyć albo wskaźników funkcji, albo std::function s. Jeśli możesz użyć std::function zamiast wskaźników, powinieneś.

To sprawia, że ​​praca kodu:

typedef function<void(void)> fp; 
+0

Jedyne, co dodam, to że używanie funkcji std :: pozwala również na użycie typu z przeciążonym operatorem(). Doskonała odpowiedź. –

+4

Jak proponuje się zmienić 'SetupIterateCabinet' (API C), aby wziąć obiekt C++? – ildjarn

+0

@ildjarn "Powinieneś użyć albo wskaźników funkcji, albo' std :: function' ". Jeśli nie może użyć 'std :: function', wówczas powinien używać wskaźników funkcji, chyba że chce zawinąć funkcję' std :: 'wokół funkcji statycznych, ale to nie będzie piękne. – mfontanini

Powiązane problemy