2009-12-18 15 views
10

Ricevo un errore di compilazione (MS VS 2008) che non capisco. Dopo averci lavorato per molte ore, è tutto sfocato e sento che c'è qualcosa di molto ovvio (e molto stupido) che mi manca. Ecco il codice essenziale:Come si chiama una funzione pointer-to-member?

typedef int (C::*PFN)(int); 

struct MAP_ENTRY 
    { 
    int id; 
    PFN pfn; 
    }; 

class C 
    { 
    ... 
    int Dispatch(int, int); 
    MAP_ENTRY *pMap; 
    ... 
    }; 

int C::Dispatch(int id, int val) 
    { 
    for (MAP_ENTRY *p = pMap; p->id != 0; ++p) 
     { 
     if (p->id == id) 
      return p->pfn(val); // <--- error here 
     } 
    return 0; 
    } 

Le rivendicazioni del compilatore in corrispondenza della freccia che il "termine non restituisce una funzione di prendere 1 argomento". Perchè no? PFN è prototipato come una funzione che accetta un argomento e MAP_ENTRY.pfn è un PFN. Cosa mi manca qui?

+0

La sintassi C è arrugginita, quindi non aggiungere come risposta, nel caso non fosse "return (* (p-> pfn)) (val);"? - –

+0

No, che restituisce l'errore "* non valido sugli operandi di tipo C :: PFN". – chrisd

+0

possibile duplicato di [Richiamo dei metodi di classe C++ tramite un puntatore di funzione] (http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) –

risposta

17

p->pfn è un puntatore di tipo puntatore-a-membro-funzione. Per chiamare una funzione tramite tale puntatore è necessario utilizzare l'operatore ->* o l'operatore .* e fornire un oggetto di tipo C come operando di sinistra. Non l'hai fatto.

Non so che si suppone oggetto di tipo C da utilizzare qui - solo tu sai che - ma nel tuo esempio è potrebbe essere*this. In tal caso, la chiamata potrebbe apparire come segue

(this->*p->pfn)(val) 

Al fine di far sembrare un po 'meno complicata, è possibile introdurre una variabile intermedia

PFN pfn = p->pfn; 
(this->*pfn)(val); 
+0

Grazie. Ora non ho solo la correzione, capisco perché. – chrisd

8

Prova

return (this->*p->pfn)(val); 
+0

SI !! Questo è tutto. Grazie mille. Voi ragazzi siete incredibili. Ho fregato per ore e ho ottenuto la risposta in meno di 10 minuti. – chrisd

-1

p-> PFN è un puntatore a funzione. Devi usare * per farlo funzionare. Modifica

(*(p->pfn))(val) 
0

Fatevi un favore e utilizzare boost::function (e spinta :: bind too!)

+9

"Da dove viene questo graffio sulla mia bicicletta?" - "Fai un favore a te stesso - compra un aereo" –

0

questo non risponde alla tua domanda, ma considera l'uso di boost :: function e boost :: bind. Introduce una dipendenza piuttosto grande nella tua base di codice, ma ne vale la pena per progetti più grandi.

1

Solo per carillon con la mia esperienza, ho incontrato un errore in g ++ causati da questa affermazione:

(this -> *stateHandler)() ; 

Dove stateHandler è un puntatore ad una funzione di membro vuoto della classe a cui fa riferimento * Questo. Il problema è stato causato dagli spazi tra l'operatore della freccia. Il seguente frammento compila bene:

(this->*stateHandler)() ; 

sto usando g ++ (GCC) 4.4.2 20.090.825 (prerelease). FWIW.

Problemi correlati