为什么不允许从VirtualBase ::*转换为Derived ::*?

Joh*_*itb 15 c++ virtual-inheritance member-pointers

昨天,我和我的同事不确定为什么语言禁止这种转换

struct A { int x; };
struct B : virtual A { };

int A::*p = &A::x;
int B::*pb = p;
Run Code Online (Sandbox Code Playgroud)

甚至演员都没有帮助.如果基本成员指针是虚拟基类,为什么标准不支持将基本成员指针转换为派生成员指针?

相关的C++标准参考:

类型"指向Bcv类型成员的指针"的prvalue T,其中B是类类型,可以转换为类型为"指向Dcv类型成员的指针"的prvalue T,其中D是派生类(第10条)B.如果B不可访问(第11条),模糊(10.2)或虚拟(10.1)基类D,或虚拟基类的基类D,则需要进行此转换的程序是不正确的.

函数和数据成员指针都会受到影响.

Tem*_*Rex 8

Lippman的" Inside the C++ Object model "对此进行了讨论:

[需要]在运行时使每个派生类对象中的虚拟基类位置可用.例如,在以下程序片段中:

class X { public: int i; }; 
class A : public virtual X { public: int j; }; 
class B : public virtual X { public: double d; }; 
class C : public A, public B { public: int k; }; 
// cannot resolve location of pa->X::i at compile-time 
void foo( const A* pa ) { pa->i = 1024; } 

main() { 
 foo( new A ); 
 foo( new C ); 
 // ... 
} 
Run Code Online (Sandbox Code Playgroud)

编译器无法修复X::i通过pa内部访问 的物理偏移量foo(),因为实际类型pa可能因每次foo()调用而异 .相反,编译器必须转换执行访问的代码,以便可以将分辨率X::i延迟到运行时.

实质上,虚基类的存在使按位复制语义无效.