J'ai trouvé quelque chose d'intéressant. Le message d'erreur dit tout. Quelle est la raison de ne pas permettre de ne pas permettre des parenthèses tout en prenant l'adresse d'une fonction de membre non statique? Je l'ai compilée sur 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;
}
ERREUR: MAIN.CPP: 14: ERREUR: ISO C++ interdit de prendre l'adresse d'une fonction de membre non qualifiée ou parenthèsized non statique pour former un pointeur à la fonction de membre. Dites '& myfoo :: foo'
Du message d'erreur, on dirait que vous n'êtes pas autorisé à prendre l'adresse d'une expression entre parenthèses. Ça vous suggère que vous réécrivez
fPtr = &(myfoo::foo); // main.cpp:14
à
fPtr = &myfoo::foo;
Ceci est dû à une partie de la spécification (§5.3.1/3) qui se lit
Un pointeur à un membre n'est formé que lorsqu'il est explicite et est utilisé et son opérande est un identifiant qualifié non enfermé entre parenthèses [...]
(mon emphase). Je ne suis pas sûr de savoir pourquoi c'est une règle (et je ne le savais pas jusqu'à présent), mais cela semble être ce que le compilateur se plaint.
J'espère que cela t'aides!
Imaginez ce code:
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);
}
};
Sans le truc avec les parenthèses, vous ne seriez pas en mesure de prendre un pointeur directement sur le membre de données de B (vous auriez besoin de moulages et de jeux de classe de base avec this
- pas bien).
Du bras:
Notez que l'adresse de l'opérateur doit être explicitement utilisée pour obtenir un pointeur au membre; Il n'y a pas de conversion implicite ... y avait-il eut, nous aurions une ambiguïté dans le contexte d'une fonction membre ... Par exemple,
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::*' }
Le IS Je viens de garder ce concept pré-standard et a explicitement mentionné que des parenthèses le rendent afin de ne pas avoir de pointeur au membre.