您将如何使用标准引号解释指向基类和派生类成员的指针的这种区别?

Ale*_*der 8 c++ pointer-to-member language-lawyer

演示

#include<iostream>
struct A { int i = 10; };
struct B : A { };

int main(){
    std::cout << "decltype(&B::i) == int A::* ? " << std::boolalpha
              << std::is_same<decltype(&B::i), int A::*>::value << '\n';    //#1
    A a;
    std::cout << a.*(&A::i) << '\n';

    std::cout << "decltype(&B::i) == int B::* ? "
              << std::is_same<decltype(&B::i), int B::*>::value << '\n';    //#2
    B b;
    std::cout << b.*(&B::i) << '\n';
}
Run Code Online (Sandbox Code Playgroud)

代码打印

decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false
10
Run Code Online (Sandbox Code Playgroud)

我在[expr.unary.op] / 3中使用了示例,其中标准说的类型&B::iint A::*,但这不是规范性的。

Sto*_*ica 8

在您链接到的段落中,请强调:

如果操作数是一个合格的-ID命名非静态或变体构件 m 某些类CT,该结果具有类型“指针类的成员C类型的T”,并且是一个指定prvalue C::m

“某些类别C”表示它不必与qualified-id提及的类别相同。在这种情况下,即使是由命名,i也是的成员A,并且仍然是的成员。因此,类型为,您可以通过测试进行验证A&B::i&B::iint A::*

std::is_same<decltype(&B::i), int A::*>::value
Run Code Online (Sandbox Code Playgroud)

根据[class.qual] / 1,成员查找遵循[class.member.lookup]中详细介绍的算法。i类别C是根据那里的规则检查成员所来自的子对象的。由于i是子对象的成员,因此A将指向成员的指针的类确定为A