Я пытаюсь понять последовательность в ошибке, выбрасываемая в этой программе:Указатель на член спутанности
#include <iostream>
class A{
public:
void test();
int x = 10;
};
void A::test(){
std::cout << x << std::endl; //(1)
std::cout << A::x << std::endl; //(2)
int* p = &x;
//int* q = &A::x; //error: cannot convert 'int A::*' to 'int*' in initialization| //(3)
}
int main(){
const int A::* a = &A::x; //(4)
A b;
b.test();
}
Выход 10 10
. Я меченый 4 пункта программы, но (3) моя самая большая забота:
x
забирается обычно внутри функции-члена.x
объекта извлекается с использованием оператора области действия и возвращается значение lvalue к объектуx
.- Учитывая
A::x
возвратилаint
именующее выражение в (2), то почему же тогда&A::x
возвращение неint*
, но вместо этого возвращаетint A::*
? Оператор области действия имеет приоритет перед оператором&
, поэтому сначала следует запуститьA::x
, возвращая значениеint
lvalue, прежде чем адрес будет удален. то есть это должно быть точно так же, как&(A::x)
? (Кстати, добавление скобок действительно работает). - Немного отличается, конечно, оператор области, ссылающийся на элемент класса, но без объекта, к которому относится.
Так почему же именно A::x
не возвращает адрес объекта x
, но вместо этого возвращает адрес элемента, игнорируя приоритет ::
перед тем &
?
Я думаю, что если бы это сработало иначе, это привело бы к большей путанице. Такая же последовательность идентификаторов и операторов, ссылающаяся на те же самые типы и элементы, что означает две разные вещи в зависимости от области действия: звучит как неприятность для меня. –
@JohnSensebe определенно. Я изначально писал «quirk», но на самом деле это очень разумный выбор, хотя он может показаться странным вначале. – Quentin