2009-12-18 10 views
10

Ich erhalte einen Kompilierfehler (MS VS 2008), den ich einfach nicht verstehe. Nachdem ich viele Stunden damit herumgespielt habe, ist alles verschwommen und ich habe das Gefühl, dass etwas sehr offensichtlich (und sehr dumm) ist, dass ich vermisse. Hier ist der wesentliche Code:Wie rufe ich eine Zeiger-zu-Stab-Funktion auf?

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

Der Compiler Ansprüche auf den Pfeil, der die „Begriff nicht auf eine Funktion unter 1 Argument wertet“. Warum nicht? PFN wird als Funktion für ein Argument erstellt, und MAP_ENTRY.pfn ist ein PFN. Was fehlt mir hier?

+0

C-Syntax ist rostig, also nicht als Antwort hinzufügen, sollte es nicht "return (* (p-> pfn)) (val);"? - –

+0

Nein, das ergibt den Fehler "* illegal bei Operanden vom Typ C :: PFN". – chrisd

+0

mögliches Duplikat von [Aufruf von C++ - Klassenmethoden über einen Funktionszeiger] (http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) –

Antwort

17

p->pfn ist ein Zeiger von Zeiger-auf-Mitglied-Funktion-Typ. Um eine Funktion über einen solchen Zeiger aufzurufen, müssen Sie entweder den Operator ->* oder den Operator .* verwenden und als linken Operanden ein Objekt vom Typ C angeben. Du hast es nicht getan.

Ich weiß nicht, welches Objekt vom Typ C sollte hier verwendet werden - Sie wissen nur, dass - aber in Ihrem Beispiel es*this sein könnte. In diesem Fall könnte der Anruf aussehen, als

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

Um es ein bisschen weniger gewunden aussehen zu lassen folgt, können Sie eine Zwischengröße

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

Danke. Jetzt habe ich nicht nur die Korrektur, ich verstehe warum. – chrisd

8

Versuchen

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

JA !! Das ist es. Vielen Dank. Ihr seid unglaublich. Ich habe stundenlang damit geschraubt und die Antwort in weniger als 10 Minuten bekommen. – chrisd

-1

p-> PFN ein Funktionszeiger ist. Sie müssen * verwenden, damit es funktioniert. Schalte auf

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

Tun Sie sich selbst einen Gefallen und nutzen boost::function (und Auftrieb einführen :: bind auch!)

+9

"Woher kommt dieses Kratzen auf meinem Fahrrad?" - "Tun Sie sich einen Gefallen - kaufen Sie ein Flugzeug" –

0

Dies beantwortet Ihre Frage nicht, aber ziehen Sie stattdessen boost :: function und boost :: bind in Betracht. Es bringt eine ziemlich große Abhängigkeit in Ihre Codebasis ein, aber es lohnt sich für größere Projekte.

1

nur mit meiner eigenen Erfahrung zu läuten, ich habe über einen Fehler in g kommt ++ durch diese Aussage verursacht:

(this -> *stateHandler)() ; 

Wo stateHandler ist ein Zeiger auf eine Lücke Memberfunktion der Klasse verwiesen durch * Dies. Das Problem wurde durch die Leerzeichen zwischen dem Pfeiloperator verursacht. Der folgende Ausschnitt kompiliert fein:

(this->*stateHandler)() ; 

Ich bin mit g ++ (GCC) 4.4.2 20.090.825 (Prerelease). FWIW.