Ошибка с адресом функции-члена в скобках - PullRequest
33 голосов
/ 20 августа 2011

Я нашел что-то интересное. Сообщение об ошибке говорит обо всем. В чем причина запрета скобок при получении адреса нестатической функции-члена? Я скомпилировал его на 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;

}

Ошибка: main.cpp: 14: ошибка: ISO C ++ запрещает принимать адрес неквалифицированной или заключенной в скобки нестатической функции-члена для формирования указателя на функцию-член. Скажите '& myfoo :: foo'

Ответы [ 2 ]

27 голосов
/ 20 августа 2011

Из сообщения об ошибке похоже, что вы не можете взять адрес выражения в скобках.Он предлагает переписать

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

до

fPtr = &myfoo::foo;

Это связано с частью спецификации (§5.3.1 / 3), которая читает

Указатель на член формируется только тогда, когда используется явное &, а его операндом является квалифицированный идентификатор , не заключенный в скобки [...]

(мой акцент).Я не уверен, почему это правило (и я до сих пор не знал этого), но, похоже, именно на это жалуется компилятор.

Надеюсь, это поможет!

16 голосов
/ 21 августа 2011

Представьте себе этот код:

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

Без хитрости с круглыми скобками вы не сможете взять указатель непосредственно на элемент данных B (вам потребуются приведения и игры базового класса с this - не хорошо).


Из ARM:

Обратите внимание, что оператор address-of должен явно использоваться для получения указателя на член;нет неявного преобразования ... Если бы это было так, у нас была бы неоднозначность в контексте функции-члена ... Например,

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

IS просто сохранил этот предварительный стандартКонцепция и явно упоминается, что скобки делают это так, что вы не получите указатель на член.

...