2009-12-18 11 views
10

Recibo un error de compilación (MS VS 2008) que simplemente no entiendo. Después de jugarlo durante muchas horas, todo está borroso y siento que hay algo muy obvio (y muy estúpido) que me estoy perdiendo. Aquí está el código esencial:¿Cómo llamo a una función de apuntador a miembro?

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

Las reclamaciones del compilador en la flecha que el "término no se evalúa a una función de tomar 1 argumento". Por qué no? PFN se prototipa como una función tomando un argumento, y MAP_ENTRY.pfn es un PFN. ¿Que me estoy perdiendo aqui?

+0

La sintaxis de C está oxidada, por lo que no agrega como respuesta, ¿no debería ser "return (* (p-> pfn)) (val);"? - –

+0

No, eso produce el error "* ilegal en operandos de tipo C :: PFN". – chrisd

+0

posible duplicado de [Llamando a los métodos de la clase C++ a través de un puntero a la función] (http://stackoverflow.com/questions/1485983/calling-c-class-methods-via-a-function-pointer) –

Respuesta

17

p->pfn es un puntero de tipo puntero a miembro-función. Para invocar una función a través de dicho puntero, debe utilizar el operador ->* o el operador .* y proporcionar un objeto del tipo C como el operando de la izquierda. No lo hiciste

No sé lo que se supone objeto de tipo C para ser utilizado aquí - sólo usted sabe que - pero en su ejemplo que podría ser *this. En ese caso, la llamada podría ser el siguiente

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

Con el fin de hacer que se vea un poco menos complicado, se puede introducir una variable intermedia

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

Gracias. Ahora no solo tengo la corrección, entiendo por qué. – chrisd

8

Trate

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

¡SÍ! Eso es. Muchas gracias. Ustedes son increíbles. Lo atornillé durante horas y obtuve la respuesta en menos de 10 minutos. – chrisd

-1

p-> PFN es un puntero de función. Necesita usar * para hacerlo funcionar. Cambio a

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

Hágase un favor y utilizar boost::function (y alza :: bind también!)

+9

"¿De dónde viene este rasguño en mi bicicleta?" - "Hazte un favor - compra un avión" –

0

esto no responde su pregunta, pero considere usar boost :: function y boost :: bind en su lugar. Introduce una dependencia bastante grande en su base de código, pero vale la pena para proyectos más grandes.

1

Sólo para interrumpiría con mi propia experiencia, me he encontrado un error en g ++ causado por esta declaración:

(this -> *stateHandler)() ; 

Dónde stateHandler es un puntero a una función miembro vacío de la clase al que hace referencia * esta. El problema fue causado por los espacios entre el operador de flecha. El siguiente fragmento compila bien:

(this->*stateHandler)() ; 

estoy usando g ++ (GCC) 4.4.2 20090825 (preliminar). FWIW.

Cuestiones relacionadas