2012-04-05 14 views
9

intento entender un concepto y un error. ¿Qué pasa con esto?std :: función con funciones de miembro no estáticas

class A 
{ 
public: 
    A() 
    { 
     std::function<void(int)> testFunc(&A::func); 
    } 

private: 
    void func(int) {} 
} 

mi pregunta, ¿es posible crear cualquier tipo de objeto que es capaz de llamar a un miembro de un caso específico en el std :: función actúa como un puntero de función miembro, excepto que sin la definición de tipo excéntrico que puede No se usará como parámetros de función en clases heredadas. por ejemplo:

class A 
{ 
public: 
    A() 
    { 
     index[WM_CREATE] = &A::close; 
     index[WM_DESTROY] = &A::destroy; 
    } 

protected: 
    map<UINT msg, void (A::*)(HWND, UINT , WPARAM, LPARAM)> index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public: 
    B() 
    { 
     index[WM_CREATE] = &B::create; // error because it's not a pointer of type A::* 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

Estoy pensando que estoy en el camino correcto de utilizar std :: funciones de este modo:

class A 
{ 
public:    //   Gigantic stl error with these two 
    A()    //       | 
    {    //       V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::close); 
     index[WM_DESTROY] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::destroy); 
    } 

protected: 
    map<UINT msg, std::function<void(HWND, UINT, WPARAM, LPARAM)> > index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public:     //    and this one 
    B()     //      | 
    {      //      V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM)>(&B::create); 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

si alguien podría explicar por qué estos gigantes errores crípticos significa y cómo arreglarlos, lo agradecería mucho.

+0

Cuando dice "llamar a un miembro de una instancia específica donde' std :: function' actúa como un puntero de función miembro ", ¿eso significa que la instancia específica se especifica en el momento de la creación de la función' std :: '¿Objeto? Esto es lo que sugiere la firma 'void (int)', pero luego el objeto resultante no actuaría "como un puntero de función miembro", sino que actuaría como una devolución de llamada/functor. Si, por otro lado, quisiste decir que el objeto 'std :: function' resultante realmente actúa como un puntero de función miembro, entonces la firma es incorrecta (por ejemplo, podría ser' void (A &, int) 'en su lugar). ¿Cuál es? –

+0

no estoy seguro de qué es un callback/functor, pero parece que estamos diferenciando entre funciones estáticas y no estáticas, y quiero que sea una función no estática. Son manipuladores, por lo que necesitan poder manipular solo a los miembros de instancias. Como en los ejemplos, quiero que se llame a esa función cuando se pasa el índice de mapa correspondiente. Simplemente, deseo hacer esto: index [WM_CREATE] (hwnd, msg, lparam, wparam); y la única forma en que puedo pensar para hacer eso es almacenar punteros de funciones o algo similar allí. No puedo hacer punteros reales porque rompe herencia :( – FatalCatharsis

+0

No se puede usar ['std :: mem_fun'] (http: //en.cppreference.com/w/cpp/utility/functional/mem_fn) en su lugar? –

Respuesta

11

Creo que el problema que tiene es que una función miembro no sólo requiere un puntero de función, sino un puntero a la objeto de llamada. En otras palabras, las funciones miembro tienen un argumento implícito adicional que es el puntero al objeto que llama.

Para establecer una función miembro de un std :: función, es necesario utilizar std :: unen de esta manera:

std::function<void(int)> testFunc(std::bind(&A::func, this, _1)); 

Esto se une el este puntero de la corriente Un ejemplo de la función por lo que tiene el puntero a la función y la instancia del objeto, que es información suficiente para llamar adecuadamente a la función. El argumento _1 indica que el primer argumento explícito se proporcionará cuando se llame a la función.

+0

error C2065: '_1': identificador no declarado. Lo llamé como 'HandlerIndex [WM_CREATE] = std :: function (std :: bind (& BasicWindow :: MsgCreate, this, _1))' – FatalCatharsis

+0

Necesita un marcador de posición para cada argumento, por lo que sería: 'std :: function (std :: bind (& BasicWindow :: MsgCreate, this, _1, _2, _3, _4))' –

+0

ah Tengo que intentarlo cuando esté en casa un poco. – FatalCatharsis

0

mi pregunta, ¿es posible crear cualquier tipo de objeto que es capaz de llamar a un miembro de una instancia específica

En este caso, la única información que falta es en realidad lo que instancia específica el objeto std::function debe usar: &A::func no se puede usar solo (por ejemplo (this->*&A::func)(0) usa &A::func con instancia *this). Proveedores:

std::function<void(int)> testFunc = std::bind(&A::func, this); 

(tener cuidado de que std::bind(&A::func, *this) y std::bind(&A::func, this) tienen semántica ligeramente diferente.)

Cuestiones relacionadas