una tipo punteros puntero programa parentesis parametros parametro llaves funciones funcion definicion declarar corchetes como balanceados analizador algoritmo c++ function-pointers pointer-to-member

c++ - tipo - Error con la dirección de la función miembro entre paréntesis



punteros como parametros de funciones en c (2)

Encontré algo interesante. El mensaje de error lo dice todo. ¿Cuál es la razón detrás de no permitir paréntesis al tomar la dirección de una función miembro no estática? Lo compilé en gcc 4.3.4.

#include <iostream> class myfoo{ public: int foo(int number){ return (number*10); } }; int main (int argc, char * const argv[]) { int (myfoo::*fPtr)(int) = NULL; fPtr = &(myfoo::foo); // main.cpp:14 return 0; }

Error: main.cpp: 14: error: ISO C ++ prohíbe tomar la dirección de una función miembro no cualificada o no entre paréntesis para formar un puntero a la función miembro. Say ''& myfoo :: foo''


A partir del mensaje de error, parece que no está permitido tomar la dirección de una expresión entre paréntesis. Está sugiriendo que reescribas

fPtr = &(myfoo::foo); // main.cpp:14

a

fPtr = &myfoo::foo;

Esto se debe a una parte de la especificación (§5.3.1 / 3) que dice

Un puntero al miembro solo se forma cuando se usa un & explícito y su operando es un id calificado que no está entre paréntesis [...]

(mi énfasis). No estoy seguro de por qué esta es una regla (y realmente no lo sabía hasta ahora), pero parece ser de lo que se queja el compilador.

¡Espero que esto ayude!


Imagina este código:

struct B { int data; }; struct C { int data; }; struct A : B, C { void f() { // error: converting "int B::*" to "int*" ? int *bData = &B::data; // OK: a normal pointer int *bData = &(B::data); } };

Sin el truco con los paréntesis, no podrías tomar un puntero directamente al miembro de datos de B (necesitarías moldes y juegos de la clase base con this , no muy bien).

Desde el ARM:

Tenga en cuenta que el operador de dirección-de-debe ser explícitamente utilizado para obtener un puntero al miembro; no hay conversión implícita ... Si lo hubiera, tendríamos una ambigüedad en el contexto de una función de miembro ... Por ejemplo,

void B::f() { int B::* p = &B::i; // OK p = B::i; // error: B::i is an int p = &i; // error: ''&i''means ''&this->i'' which is an ''int*'' int *q = &i; // OK q = B::i; // error: ''B::i is an int q = &B::i; // error: ''&B::i'' is an ''int B::*'' }

El IS simplemente mantuvo este concepto previo al estándar y mencionó explícitamente que los paréntesis lo hacen para que no se obtenga un puntero al miembro.