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



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::*,但这不是规范性的。

从你链接到的段落中,强调我的:

如果操作数是命名非静态或变体成员的限定 IDm某些类C类型为T时,结果的类型为 "指向成员的指针"TC",是指定C::m的 prvalue 。

"某些类C"意味着它不必与限定ID提到的类相同。在这种情况下,iA的成员,即使被&B::i命名,它仍然是A的成员。因此,&B::i的类型是int A::*的,您可以通过测试进行验证

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

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

相关内容

  • 没有找到相关文章

最新更新