class Base {
virtual void dummy() = 0;
// this is to generate a vtable, but note there is no virtual f()
};
class A : public Base {
public:
void f() { /* ... */ };
void dummy() {};
};
class B : public Base {
public:
void f() { /* different implementation from A */ };
void dummy() {};
};
template<class T1, class T2, class T3>
void doStuff(T1 &x, T2 &y, T3 &z) {
for (int i=1; i<100000; ++i) {
x.f();
y.f();
z.f();
}
}
void doStuff(Base &x, Base &y, Base &z) {
A *a_x = dynamic_cast<A*>(&x);
B *b_x = dynamic_cast<B*>(&x);
A *a_y = dynamic_cast<A*>(&y);
B *b_y = dynamic_cast<B*>(&y);
A *a_z = dynamic_cast<A*>(&z);
B *b_z = dynamic_cast<B*>(&z);
if (a_x && a_y && a_z) {
doStuff(*a_x, *a_y, *a_z);
} else if (a_x && a_y && b_z) {
doStuff(*a_x, *a_y, *b_z);
}
// ... and so on for all eight combinations of A and B.
}
int main() {
Base *x = new A();
Base *y = new B();
Base *z = new A();
doStuff(*x, *y, *z);
// oops - this instantiates to doStuff(Base &, Base &, Base &)
// and there's no Base::f().
}
Y2xhc3MgQmFzZSB7CiAgICB2aXJ0dWFsIHZvaWQgZHVtbXkoKSA9IDA7CiAgICAvLyB0aGlzIGlzIHRvIGdlbmVyYXRlIGEgdnRhYmxlLCBidXQgbm90ZSB0aGVyZSBpcyBubyB2aXJ0dWFsIGYoKQp9OwoKY2xhc3MgQSA6IHB1YmxpYyBCYXNlIHsKcHVibGljOgogICAgdm9pZCBmKCkgeyAvKiAuLi4gKi8gfTsKICAgIHZvaWQgZHVtbXkoKSB7fTsKfTsKCmNsYXNzIEIgOiBwdWJsaWMgQmFzZSB7CnB1YmxpYzoKICAgIHZvaWQgZigpIHsgLyogZGlmZmVyZW50IGltcGxlbWVudGF0aW9uIGZyb20gQSAqLyB9OwogICAgdm9pZCBkdW1teSgpIHt9Owp9OwoKdGVtcGxhdGU8Y2xhc3MgVDEsIGNsYXNzIFQyLCBjbGFzcyBUMz4Kdm9pZCBkb1N0dWZmKFQxICZ4LCBUMiAmeSwgVDMgJnopIHsKICAgIGZvciAoaW50IGk9MTsgaTwxMDAwMDA7ICsraSkgewogICAgICAgIHguZigpOwogICAgICAgIHkuZigpOwogICAgICAgIHouZigpOwogICAgfQp9Cgp2b2lkIGRvU3R1ZmYoQmFzZSAmeCwgQmFzZSAmeSwgQmFzZSAmeikgewogICAgQSAqYV94ID0gZHluYW1pY19jYXN0PEEqPigmeCk7CiAgICBCICpiX3ggPSBkeW5hbWljX2Nhc3Q8Qio+KCZ4KTsKICAgIEEgKmFfeSA9IGR5bmFtaWNfY2FzdDxBKj4oJnkpOwogICAgQiAqYl95ID0gZHluYW1pY19jYXN0PEIqPigmeSk7CiAgICBBICphX3ogPSBkeW5hbWljX2Nhc3Q8QSo+KCZ6KTsKICAgIEIgKmJfeiA9IGR5bmFtaWNfY2FzdDxCKj4oJnopOwogICAgaWYgKGFfeCAmJiBhX3kgJiYgYV96KSB7CiAgICAgICAgZG9TdHVmZigqYV94LCAqYV95LCAqYV96KTsKICAgIH0gZWxzZSBpZiAoYV94ICYmIGFfeSAmJiBiX3opIHsKICAgICAgICBkb1N0dWZmKCphX3gsICphX3ksICpiX3opOwogICAgfQogICAgLy8gLi4uIGFuZCBzbyBvbiBmb3IgYWxsIGVpZ2h0IGNvbWJpbmF0aW9ucyBvZiBBIGFuZCBCLgp9CgppbnQgbWFpbigpIHsKICAgIEJhc2UgKnggPSBuZXcgQSgpOwogICAgQmFzZSAqeSA9IG5ldyBCKCk7CiAgICBCYXNlICp6ID0gbmV3IEEoKTsKCiAgICBkb1N0dWZmKCp4LCAqeSwgKnopOwogICAgLy8gb29wcyAtIHRoaXMgaW5zdGFudGlhdGVzIHRvIGRvU3R1ZmYoQmFzZSAmLCBCYXNlICYsIEJhc2UgJikKICAgIC8vIGFuZCB0aGVyZSdzIG5vIEJhc2U6OmYoKS4KfQ==