指向成员的混淆

Ant*_*ant 7 c++ pointer-to-member c++11

我试图理解这个程序中引发的错误的一致性:

#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();

}
Run Code Online (Sandbox Code Playgroud)

输出是10 10.我标记了该计划的4个点,但(3)是我最关心的问题:

  1. x 通常从成员函数内部获取.
  2. x使用范围运算符获取对象的对象,x并返回对象的左值.
  3. 给定A::x返回int(2)中的左值,为什么然后&A::x返回不是int*,而是返回int A::*?范围运算符甚至优先于&运算符,因此A::x应首先运行int,在获取地址之前返回左值.即这应该是一样的&(A::x)吗?(添加括号实际上确实有效).
  4. 这里有点不同,范围操作符引用类成员但没有引用的对象.

那么为什么A::x不返回对象x的地址而是返回成员的地址,忽略::之前的优先级&

Que*_*tin 8

基本上,只是语法&A::x(没有变化)被选择为指向成员的指针.

例如,如果你写,&(A::x)你将得到你期望的普通指针.

可以在此处找到有关指向成员的更多信息,包括有关此属性的说明.


Okt*_*ist 4

C++ 标准没有明确指定运算符优先级;可以从语法规则中隐式地推导出运算符优先级,但是这种方法无法理解偶尔出现的特殊情况,这种情况不适合传统的运算符优先级模型。

[expr.unary.op]/3:

一元运算符的结果&是指向其操作数的指针。操作数应为左值或限定 ID。如果操作数是 命名某个类型的某个类的非静态或变体成员的限定 ID,则结果的类型为“指向类型的类的成员的指针” ,并且是指定的纯右值。否则,如果表达式的类型为,则结果的类型为“指向”,并且是纯右值,即指定对象的地址或指向指定函数的指针。mCTCTC::mTT

/4:

&仅当使用显式且其操作数是未括在括号中的限定 ID时,才会形成指向成员的指针。[注意: 也就是说,限定 ID 括在括号中的表达式&(qualified-id)不会形成“指向成员的指针”类型的表达式。

[expr.prim.general]/9:

表示一个类的嵌套名称说明符(可选地后跟关键字template,然后后跟该类或其基类之一的成员的名称)是合格的 id

所有这些加起来就是,如果是非联合类的非静态成员,则该形式的表达式具有“指向类成员的&A::x指针”类型,并且运算符优先级对此没有影响。xAxA