2009-12-18 4 views
10

Je reçois une erreur de compilation (MS VS 2008) que je ne comprends pas. Après avoir joué pendant de nombreuses heures, tout est flou et j'ai l'impression qu'il y a quelque chose de très évident (et très stupide) qui me manque. Voici le code essentiel:Comment appeler une fonction pointeur vers membre?

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

Les revendications compilateur à la flèche que le « terme ne pas prendre une fonction 1 argument ». Pourquoi pas? PFN est prototypé comme une fonction prenant un argument, et MAP_ENTRY.pfn est un PFN. Qu'est-ce que j'oublie ici?

+0

La syntaxe C est rouillée, donc ne pas ajouter comme réponse, ne devrait-elle pas être "return (* (p-> pfn)) (val);"? - –

+0

Non, cela donne l'erreur "* illégal sur les opérandes de type C :: PFN". – chrisd

+0

duplication possible de [Appelant des méthodes de classe C++ via un pointeur de fonction] (http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) –

Répondre

17

p->pfn est un pointeur de type fonction pointeur à membre. Pour appeler une fonction via un tel pointeur, vous devez utiliser l'opérateur ->* ou l'opérateur .* et fournir un objet de type C comme opérande de gauche. Tu ne l'as pas fait.

Je ne sais pas quel objet de type C est censé être utilisé ici - que vous savez que - mais dans votre exemple, il pourrait être *this. Dans ce cas, l'appel pourrait se présenter comme suit

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

Afin de faire paraître un peu moins alambiquée, vous pouvez introduire une variable intermédiaire

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

Merci. Maintenant, je n'ai pas seulement la correction, je comprends pourquoi. – chrisd

8

Essayez

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

OUI !! C'est tout. Merci beaucoup. Vous êtes incroyables. J'ai baisé avec ça pendant des heures et j'ai eu la réponse en moins de 10 minutes. – chrisd

-1

P-> PFN est un pointeur de fonction. Vous devez utiliser * pour le faire fonctionner. Modification de

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

Faites-vous une faveur et utiliser boost::function (et coup de pouce :: bind too!)

+9

"D'où vient cette rayure sur mon vélo?" - "Faites-vous une faveur - achetez un avion" –

0

Ceci ne répond pas à votre question, mais pensez à utiliser boost :: function et boost :: bind à la place. Cela introduit une très grande dépendance dans votre base de code, mais cela en vaut la peine pour les projets plus importants.

1

Juste à sonner avec ma propre expérience, je suis tombé sur une erreur en g ++ provoquée par cette déclaration:

(this -> *stateHandler)() ; 

Où stateHandler est un pointeur vers une fonction membre de vide de la classe référencée par * ce. Le problème a été causé par les espaces entre l'opérateur de flèche. L'extrait suivant compile bien:

(this->*stateHandler)() ; 

J'utilise g ++ (GCC) 4.4.2 20.090.825 (préversion). FWIW.

Questions connexes