2012-05-11 27 views
10

Aquí es un código:std :: función -> función de puntero

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

Originalmente Necesito hacer un puntero de función del método de clase no estática porque tengo que guardar los datos entre los llamados de función. Intenté std::tr1::bind y boost::bind, pero devuelven el objeto funcional, no el puntero, que, como puedo ver, no se puede "convertir" al puntero funcional puro. Mientras que la firma de función (SetupIterateCabinet) exige un puntero func puro exactamente.

Necesito un consejo sobre cómo solucionar el problema. Gracias.

Respuesta

7

Usted ha simplificado en exceso en gran medida su verdadero problema y se volvió a su pregunta en un XY problem. Volvamos a su pregunta real: cómo llamar al SetupIterateCabinet con una función de miembro no estático como devolución de llamada.

dado alguna clase:

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

Para utilizar MyClass::MyCallback como tercer argumento a SetupIterateCabinet, tiene que pasar una MyClass* para el argumento Context y utilizar una función de cuña sencilla de tomar argumento de que Context y hacer lo correcto con él:

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

Eso funciona, ¡gracias! – fogbit

8

No se puede convertir un std::function en un puntero de función (puede hacer lo contrario). Debe usar los punteros a las funciones o std::function s. Si puede usar std::function en lugar de punteros, entonces debería hacerlo.

Esto hace que su trabajo código:

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

Lo único que agregaré es que usar std :: function también le permite usar un tipo con operador() sobrecargado. Excelente respuesta –

+4

¿Cómo propone que cambie 'SetupIterateCabinet' (una API C) para tomar un objeto C++? – ildjarn

+0

@ildjarn "Debería utilizar cualquiera de los punteros de función o' std :: function' ". Si no puede usar 'std :: function' entonces debería usar punteros a la función, a menos que quiera envolver su' std :: function's alrededor de funciones estáticas, pero eso no va a ser bonito. – mfontanini

Cuestiones relacionadas