C++ C++;-为什么不是';钻石遗传的这种结构不会引起歧义吗?

C++ C++;-为什么不是';钻石遗传的这种结构不会引起歧义吗?,c++,inheritance,overriding,virtual-inheritance,C++,Inheritance,Overriding,Virtual Inheritance,我已经浏览了几十个多重继承问题,但没有找到这个问题的答案 我理解为什么这不会编译: struct B{ virtual void f(){ printf("B"); } }; struct C1 : virtual B{ void f() override{ printf("C1"); } }; struct C2: virtual B{ void f() override{

我已经浏览了几十个多重继承问题,但没有找到这个问题的答案

我理解为什么这不会编译:

struct B{
    virtual void f(){
        printf("B");
    }
};

struct C1 : virtual B{
   void f() override{
        printf("C1");
    }
};

struct C2: virtual B{
    void f() override{
        printf("C2")
    }
};

struct D: C1,C2{
    
};
因为没有办法确定哪个
f
应该在
B
的vtable中

然而,我很惊讶地看到,这段代码将编译:

struct B{
    virtual void f(){
        printf("B");
    }
};

struct C1 : virtual B{
   void f() override{
        printf("C1");
    }
};

struct C2: virtual B{

};

struct D: C1,C2{
    
};
我(错误的)直觉是,我们仍然有两条从
D
B
的路径,在每一条路径中,
f
被覆盖的最后位置是不同的-在一条路径中,它在
C1
中,在另一条路径中,它在
B
中,但这是编译的


为什么这不会引起歧义?

因为C1::f1覆盖了B::f1,所以它将优先用于任何动态类型为C1或任何子类的对象


在不明确的情况下,虽然C1::f1和C2::f1都覆盖了B::f1,但它们并不相互覆盖,因此二者之间存在歧义——它们都覆盖了一个公共基函数这一事实无关紧要。

我猜
D
中的所有内容实际上在每个“级别”上都被覆盖一次因为
B
没有成员,所以它们也没有“冲突”。但这只是一个盲目的猜测。