Errore con l’indirizzo della funzione membro parentesi

Ho trovato qualcosa di interessante. Il messaggio di errore dice tutto. Qual è la ragione alla base del non consentire le parentesi mentre si prende l’indirizzo di una funzione membro non statica? L’ho compilato su gcc 4.3.4.

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

Errore: main.cpp: 14: errore: ISO C ++ vieta di prendere l’indirizzo di una funzione membro non statico o non classificato tra parentesi per formare un puntatore alla funzione membro. Dì “& myfoo :: foo”

Dal messaggio di errore, sembra che non ti sia permesso di prendere l’indirizzo di un’espressione parentesi. Sta suggerendo di riscrivere

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

a

 fPtr = &myfoo::foo; 

Ciò è dovuto a una parte delle specifiche (§5.3.1 / 3) che si legge

Un puntatore al membro viene formato solo quando viene utilizzato un esplicito e il suo operando è un id qualificato non racchiuso tra parentesi […]

(la mia enfasi). Non sono sicuro del motivo per cui questa è una regola (e in realtà non lo sapevo fino ad ora), ma questo sembra essere ciò di cui il compilatore si lamenta.

Spero che questo ti aiuti!

Immagina questo codice:

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

Senza il trucco con le parentesi, non sareste in grado di portare un puntatore direttamente al membro dei dati di B (avreste bisogno di cast e giochi di class base con this – non bello).


Dal ARM:

Si noti che l’operatore address-of deve essere esplicitamente utilizzato per ottenere un puntatore al membro; non c’è una conversione implicita … Se ci fosse stata, avremmo un’ambiguità nel contesto di una funzione membro … Ad esempio,

 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::*' } 

L’IS ha mantenuto questo concetto pre-standard e ha esplicitamente menzionato che le parentesi fanno in modo che non si ottenga un puntatore al membro.