#include <iostream>
struct V {
virtual void f(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
virtual void g(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
struct A : virtual V {
virtual void f(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
};
struct B : virtual V {
virtual void g(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
B(V*, A*);
};
struct D : A, B {
virtual void f(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
virtual void g(){std::cout << __PRETTY_FUNCTION__ << std::endl;}
D() : B((A*)this, this) { }
};
B::B(V* v, A* a) {
f(); // calls V::f, not A::f
g(); // calls B::g, not D::g
v->g(); // v is base of B, the call is well-defined, calls B::g
a->f(); // undefined behavior, a’s type not a base of B
}
int main(){
D d;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKc3RydWN0IFYgewoJdmlydHVhbCB2b2lkIGYoKXtzdGQ6OmNvdXQgPDwgX19QUkVUVFlfRlVOQ1RJT05fXyA8PCBzdGQ6OmVuZGw7fQoJdmlydHVhbCB2b2lkIGcoKXtzdGQ6OmNvdXQgPDwgX19QUkVUVFlfRlVOQ1RJT05fXyA8PCBzdGQ6OmVuZGw7fQp9OwpzdHJ1Y3QgQSA6IHZpcnR1YWwgViB7Cgl2aXJ0dWFsIHZvaWQgZigpe3N0ZDo6Y291dCA8PCBfX1BSRVRUWV9GVU5DVElPTl9fIDw8IHN0ZDo6ZW5kbDt9Cn07CnN0cnVjdCBCIDogdmlydHVhbCBWIHsKCXZpcnR1YWwgdm9pZCBnKCl7c3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsO30KCUIoViosIEEqKTsKfTsKc3RydWN0IEQgOiBBLCBCIHsKCXZpcnR1YWwgdm9pZCBmKCl7c3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsO30KCXZpcnR1YWwgdm9pZCBnKCl7c3RkOjpjb3V0IDw8IF9fUFJFVFRZX0ZVTkNUSU9OX18gPDwgc3RkOjplbmRsO30KCUQoKSA6IEIoKEEqKXRoaXMsIHRoaXMpIHsgfQp9OwoKQjo6QihWKiB2LCBBKiBhKSB7CglmKCk7IC8vIGNhbGxzIFY6OmYsIG5vdCBBOjpmCglnKCk7IC8vIGNhbGxzIEI6OmcsIG5vdCBEOjpnCgl2LT5nKCk7IC8vIHYgaXMgYmFzZSBvZiBCLCB0aGUgY2FsbCBpcyB3ZWxsLWRlZmluZWQsIGNhbGxzIEI6OmcKCWEtPmYoKTsgLy8gdW5kZWZpbmVkIGJlaGF2aW9yLCBh4oCZcyB0eXBlIG5vdCBhIGJhc2Ugb2YgQgp9CgppbnQgbWFpbigpewogICAgRCBkOwp9