2013-05-13 10 views
5

So che questo è già un argomento discusso a lungo, ma non ho ancora trovato una risposta che mi soddisfi.C++ 11: puntatori alla funzione membro utilizzando std :: function :: target()

Domanda in breve: anche utilizzando le funzionalità function :: target() del C++ 11, non è possibile passare i puntatori di funzioni dei membri ai metodi c-style?

Il seguente codice non funziona: la chiamata a mbf.target() restituirà 0 e quindi viene generato un SEGFAULT. E non capisco perché, perché lego la funzione membro a un oggetto funzione generico, quindi il tipo dovrebbe andare bene.

Cosa sto sbagliando o sto cercando di fare qualcosa di impossibile?

#include <functional> 
using namespace std; 

typedef void (*CBType)(int, int); 
CBType myCB = 0; 

void regCallback(CBType cb) 
{ 
    myCB = cb; 
} 

class A 
{ 
public: 
    void memberCB(int a, int b) {} 

    void registerCallback() 
    { 
     auto mbMem = mem_fn(&A::memberCB); 
     function<void(int,int)> mbf = 
      bind(mbMem, *this, placeholders::_1, placeholders::_2); 
     regCallback(*mbf.target<void(*)(int,int)>()); 
    } 
}; 


int main() 
{ 
    A inst; 
    inst.registerCallback(); 
} 
+2

C'è una differenza tra 'typedef void (* CBType) (int, int);' e 'typedef void (A :: * CBType) (int, int);'. Penso che tu stia scherzando. Ricorda che il tipo di '& A :: memberCB' è' void (A :: *) (int, int) 'e non' void (*) (int, int) '. Il tuo codice non viene compilato, puoi fornire un codice di compilazione? – iammilind

+0

Giusto, ho aggiunto il file di intestazione e lo spazio dei nomi. Quindi compila usando g ++ e il flag del compilatore "-std = C++ 0x" – bobbel

+2

Impossibile. 'target' è pensato per recuperare un puntatore a funzione precedentemente memorizzato. Non ha magia e non può produrre oro^Indicatori di Wfunction fuori piombo^Wanything else. Puoi dimenticarti di 'target' qui; ha un caso d'uso completamente diverso (e piuttosto raro). –

risposta

3

funzionare il membro non è di tipo void (*)(int, int) è di tipo void (A::*)(int, int). Pertanto, target restituisce nullptr poiché si tenta di eseguire il cast sul tipo sbagliato. Vorrei raccomandare solo di fare CBType a std::function<void(int, int)>.

+0

È interessante. Quindi una dichiarazione "function mbf = ..." mantiene in qualche modo un riferimento di tipo interno alla classe e non può astrarre il tipo al puntatore non membro? – bobbel

+0

Anche se tecnicamente possibile, non può essere corretto. La funzionalità della funzione di classe dipende dall'oggetto a cui è legata, fa parte del suo contesto. – SomeWittyUsername

+0

Sì, certo. Ma è per questo che voglio legare l'oggetto alla funzione. Ma sembra che io abbia una visione di livello troppo alto delle funzionalità di std :: function. – bobbel