Ошибка с адресом функции-члена в скобки
Я нашел что-то интересное. В сообщении об ошибке говорится все. В чем причина того, что в круглых скобках не указывается адрес нестатической функции-члена? Я скомпилировал его на 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 С++ запрещает принимать адрес неквалифицированной или нестационарной нестационарной функции-члена для формирования указателя на функцию-член. Скажем '& myfoo:: foo'
Ответы
Ответ 1
Из сообщения об ошибке похоже, что вам не разрешено принимать адрес выражения в скобках. Это означает, что вы переписываете
fPtr = &(myfoo::foo); // main.cpp:14
к
fPtr = &myfoo::foo;
Это связано с частью спецификации (& sect; 5.3.1/3), которая читает
Указатель на член формируется только тогда, когда явный и используется, а его операнд - это идентификатор , не заключенный в круглые скобки <... >
(мой акцент). Я не уверен, почему это правило (и я до сих пор не знал об этом до сих пор), но похоже, что компилятор жалуется.
Надеюсь, это поможет!
Ответ 2
Представьте этот код:
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:
Обратите внимание, что адрес-оператор должен быть явно использован для получения указателя на элемент; нет никакого неявного преобразования... Если бы было, у нас была бы двусмысленность в контексте функции-члена... Например,
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 просто сохранил эту концепцию pre-Standard и прямо упомянул, что круглые скобки делают это так, что вы не получаете указатель на член.