Pregunta Error con la dirección de la función miembro entre paréntesis


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'


32
2017-08-20 19:39


origen


Respuestas:


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 no encerrado 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!


25
2017-08-20 19:44



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 se podría tomar un puntero directamente al miembro de datos de B (se necesitarían moldes de clase base y juegos con this - No está 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.


14
2017-08-21 13:42