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

时间:2019-06-16 13:36:19

标签: c++ language-lawyer pointer-to-member

demo

#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';
}

代码打印

decltype(&B::i) == int A::* ? true
10
decltype(&B::i) == int B::* ? false
10

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

1 个答案:

答案 0 :(得分:8)

在您链接的段落中,重点是我的:

  

如果操作数是命名非静态或变体成员的合格ID   m 某类C的类型T ,结果的类型为“指向成员的指针   类型为C的类T的名称,并且是表示C::m的prvalue。

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

std::is_same<decltype(&B::i), int A::*>::value

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