#include <iostream>
using namespace std;
struct EventReceiverBase {
virtual ~EventReceiverBase() { }
};
template<typename T>
struct EventReceiver : public virtual EventReceiverBase {
virtual void receiveEvent(T* pSender) = 0;
};
struct EventSender {
EventReceiverBase* pReceiver;
template<typename T>
void sendEvent(T* pSender) {
EventReceiver<T>* pCastedReceiver =
dynamic_cast<EventReceiver<T>*>(pReceiver);
// HERE IS THE PROBLEM
// pCastedReceiver is null. T is BaseSender. The pointer
// being casted is really of type EventReceiver<DerivedSender>*,
// but it tries to cast to EventReceiver<BaseSender>*, and that
// fails.
pCastedReceiver->receiveEvent(pSender);
}
};
struct BaseSender : public virtual EventSender {
};
struct DerivedSender : public BaseSender {
void f() {
sendEvent(this);
}
};
struct MyClass : public virtual EventReceiver<DerivedSender> {
void receiveEvent(DerivedSender* pSender) { }
};
int main() {
MyClass my;
DerivedSender derivedSender;
derivedSender.pReceiver = &my;
derivedSender.f();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnN0cnVjdCBFdmVudFJlY2VpdmVyQmFzZSB7CiAgICB2aXJ0dWFsIH5FdmVudFJlY2VpdmVyQmFzZSgpIHsgfQp9OwoKdGVtcGxhdGU8dHlwZW5hbWUgVD4Kc3RydWN0IEV2ZW50UmVjZWl2ZXIgOiBwdWJsaWMgdmlydHVhbCBFdmVudFJlY2VpdmVyQmFzZSB7CiAgICB2aXJ0dWFsIHZvaWQgcmVjZWl2ZUV2ZW50KFQqIHBTZW5kZXIpID0gMDsKfTsKCnN0cnVjdCBFdmVudFNlbmRlciB7CiAgICBFdmVudFJlY2VpdmVyQmFzZSogcFJlY2VpdmVyOwoKICAgIHRlbXBsYXRlPHR5cGVuYW1lIFQ+CiAgICB2b2lkIHNlbmRFdmVudChUKiBwU2VuZGVyKSB7CiAgICAgICAgRXZlbnRSZWNlaXZlcjxUPiogcENhc3RlZFJlY2VpdmVyID0KICAgICAgICAgICAgZHluYW1pY19jYXN0PEV2ZW50UmVjZWl2ZXI8VD4qPihwUmVjZWl2ZXIpOwogICAgICAgIC8vIEhFUkUgSVMgVEhFIFBST0JMRU0KICAgICAgICAvLyBwQ2FzdGVkUmVjZWl2ZXIgaXMgbnVsbC4gVCBpcyBCYXNlU2VuZGVyLiBUaGUgcG9pbnRlcgogICAgICAgIC8vIGJlaW5nIGNhc3RlZCBpcyByZWFsbHkgb2YgdHlwZSBFdmVudFJlY2VpdmVyPERlcml2ZWRTZW5kZXI+KiwKICAgICAgICAvLyBidXQgaXQgdHJpZXMgdG8gY2FzdCB0byBFdmVudFJlY2VpdmVyPEJhc2VTZW5kZXI+KiwgYW5kIHRoYXQKICAgICAgICAvLyBmYWlscy4KICAgICAgICBwQ2FzdGVkUmVjZWl2ZXItPnJlY2VpdmVFdmVudChwU2VuZGVyKTsKICAgIH0KfTsKCnN0cnVjdCBCYXNlU2VuZGVyIDogcHVibGljIHZpcnR1YWwgRXZlbnRTZW5kZXIgewp9OwpzdHJ1Y3QgRGVyaXZlZFNlbmRlciA6IHB1YmxpYyBCYXNlU2VuZGVyIHsKICAgIHZvaWQgZigpIHsKICAgICAgICBzZW5kRXZlbnQodGhpcyk7CiAgICB9Cn07CgpzdHJ1Y3QgTXlDbGFzcyA6IHB1YmxpYyB2aXJ0dWFsIEV2ZW50UmVjZWl2ZXI8RGVyaXZlZFNlbmRlcj4gewogICAgdm9pZCByZWNlaXZlRXZlbnQoRGVyaXZlZFNlbmRlciogcFNlbmRlcikgeyB9Cn07CgppbnQgbWFpbigpIHsKICAgIE15Q2xhc3MgbXk7CiAgICBEZXJpdmVkU2VuZGVyIGRlcml2ZWRTZW5kZXI7CiAgICBkZXJpdmVkU2VuZGVyLnBSZWNlaXZlciA9ICZteTsKICAgIGRlcml2ZWRTZW5kZXIuZigpOwogICAgcmV0dXJuIDA7Cn0=