web-dev-qa-db-fra.com

Erreur avec l'adresse de la fonction de membre parenthésisée

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'

33
Mahesh

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!

27
templatetypedef

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.

16